1.把二元查找树转变成排序的双向链表(树)
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
我的解答:
#
include
<iostream
>
# include <string >
# include <vector >
# include <bitset >
# include <string >
# include <sstream >
using namespace std;
struct BSTreeNode{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
void addBSTreeNode(BSTreeNode * &T, int node){ //注意:由于要给T这个指针赋值(T = new BSTreeNode()),故此处必须用引用!
if(T){
if(T - >m_nValue > node){ //添加到左子树
addBSTreeNode(T - >m_pLeft, node);
} else if(T - >m_nValue < node){ //添加到右子树
addBSTreeNode(T - >m_pRight, node);
} else{
cout << "加入重复节点" <<endl;
}
} else{
T = new BSTreeNode(); //添加节点
T - >m_nValue = node;
T - >m_pLeft = NULL;
T - >m_pRight = NULL;
}
}
BSTreeNode *lastNode = NULL; //储存链表中的上一个节点
BSTreeNode *startNode = NULL; //存双向链表的头节点
void midOrderTraverse(BSTreeNode *T){
if(T){
midOrderTraverse(T - >m_pLeft); //访问左子树
T - >m_pLeft =lastNode; //当前节点的m_pLeft指向上一节点
if(lastNode){
lastNode - >m_pRight = T; //上一个节点的m_pRight指向当前节点
} else{
startNode = T; //上一个节点为空,则该节点为头结点
}
lastNode = T; //当前节点变为上一节点
midOrderTraverse(T - >m_pRight); //访问右子树
}
}
int main(){
BSTreeNode *pRoot =NULL;
//初始化二叉搜索树
addBSTreeNode(pRoot, 10);
addBSTreeNode(pRoot, 4);
addBSTreeNode(pRoot, 6);
addBSTreeNode(pRoot, 8);
addBSTreeNode(pRoot, 12);
addBSTreeNode(pRoot, 14);
addBSTreeNode(pRoot, 15);
addBSTreeNode(pRoot, 16);
//中序遍历变为双向链表
midOrderTraverse(pRoot);
//打印输出
while(startNode){
cout <<startNode - >m_nValue <<endl;
startNode = startNode - >m_pRight;
}
return 0;
}
# include <string >
# include <vector >
# include <bitset >
# include <string >
# include <sstream >
using namespace std;
struct BSTreeNode{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
void addBSTreeNode(BSTreeNode * &T, int node){ //注意:由于要给T这个指针赋值(T = new BSTreeNode()),故此处必须用引用!
if(T){
if(T - >m_nValue > node){ //添加到左子树
addBSTreeNode(T - >m_pLeft, node);
} else if(T - >m_nValue < node){ //添加到右子树
addBSTreeNode(T - >m_pRight, node);
} else{
cout << "加入重复节点" <<endl;
}
} else{
T = new BSTreeNode(); //添加节点
T - >m_nValue = node;
T - >m_pLeft = NULL;
T - >m_pRight = NULL;
}
}
BSTreeNode *lastNode = NULL; //储存链表中的上一个节点
BSTreeNode *startNode = NULL; //存双向链表的头节点
void midOrderTraverse(BSTreeNode *T){
if(T){
midOrderTraverse(T - >m_pLeft); //访问左子树
T - >m_pLeft =lastNode; //当前节点的m_pLeft指向上一节点
if(lastNode){
lastNode - >m_pRight = T; //上一个节点的m_pRight指向当前节点
} else{
startNode = T; //上一个节点为空,则该节点为头结点
}
lastNode = T; //当前节点变为上一节点
midOrderTraverse(T - >m_pRight); //访问右子树
}
}
int main(){
BSTreeNode *pRoot =NULL;
//初始化二叉搜索树
addBSTreeNode(pRoot, 10);
addBSTreeNode(pRoot, 4);
addBSTreeNode(pRoot, 6);
addBSTreeNode(pRoot, 8);
addBSTreeNode(pRoot, 12);
addBSTreeNode(pRoot, 14);
addBSTreeNode(pRoot, 15);
addBSTreeNode(pRoot, 16);
//中序遍历变为双向链表
midOrderTraverse(pRoot);
//打印输出
while(startNode){
cout <<startNode - >m_nValue <<endl;
startNode = startNode - >m_pRight;
}
return 0;
}
心得:
1、注意形参中引用的作用,如在addBSTreeNode函数中行参T加上&,才能是给T赋值有效!
2、二叉树的遍历:采用递归,流程如下
Traverse(BiTree
*T){
if(T){ //T不为空
PreOrderVisitDate(T - >Data) //先序遍历
Traverse(T - >leftChild) //访问左子树
MidOrderVisitDate(T - >Data) //中序遍历
Traverse(T - >rightChild) //访问右子树
postOrdrtVisitDate(T - >Data) //后序遍历
}
}
if(T){ //T不为空
PreOrderVisitDate(T - >Data) //先序遍历
Traverse(T - >leftChild) //访问左子树
MidOrderVisitDate(T - >Data) //中序遍历
Traverse(T - >rightChild) //访问右子树
postOrdrtVisitDate(T - >Data) //后序遍历
}
}