前提引入:
这部分介绍本章使用的基本存储结构以及创建程序:
这里使用的二叉树为链式二叉树,基本存储结构如下:
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
二叉树的创建程序如下:
void creat(BiTree &Node){
char data;
data = getchar();
if('#'==data)
Node = NULL;
else{
Node = (BiTNode*)malloc(sizeof(BiTNode));
Node -> data = data;
creat(Node->lchild);
creat(Node->rchild);
}
}
该入栈采用满二叉树的前序序列入栈(也就是说没有结点的地方要以NULL补全,也就是#号)
如下图结构所示:
想要将左边这棵树入栈需要用序列:ABD##E###
右边同理:ABD###C##
遍历部分:
使用递归:
前序遍历:
以这两颗树为例,他们的前序遍历的走过的结点的顺序如下:
void preOrderTree(BiTNode* Node){
if(Node){
printf("%c ",Node->data);
preOrderTree(Node->lchild);
preOrderTree(Node->rchild);
}
}
输出分别为:
左:A B D E
右:A B D C
中序遍历:
void midOrderTree(BiTNode* Node){
if(Node){
midOrderTree(Node->lchild);
printf("%c ",Node->data);
midOrderTree(Node->rchild);
}
}
输出分别为:
左:D B E A
右:D B A C
后续遍历:
void postOrderTree(BiTNode* Node){
if(Node){
postOrderTree(Node->lchild);
postOrderTree(Node->rchild);
printf("%c ",Node->data);
}
}
输出分别为:
左:D E B A
右:D B C A
非递归:
非递归前序遍历:
可以使用数据结构栈来存储结点,完成非递归的前序遍历。
大致步骤图解(非完整):
void preOrderTree2(BiTree T){
stack<BiTree> S;
BiTree p = T;
while(p||!S.empty()){
if(p){
printf("%c ",p->data);
S.push(p);
p = p->lchild;
}else{
p = S.top();
S.pop();
p = p ->rchild;
}
}
}
非递归中序遍历:
同样的,也可以跟前序遍历一样,使用一个栈来保存结点信息,只是在输出的时候需要更改代码位置。
大致步骤图解如下(非完整) :
void midOrderTree2(BiTree T){
stack<BiTree> S;
BiTree p = T;
while(p||!S.empty()){
if(p){
S.push(p);
p = p->lchild;
}
else{
p = S.top();
S.pop();
printf("%c ",p->data);
p = p->rchild;
}
}
}
非递归后序遍历:
非递归后续遍历相比于前序和中序更加复杂一些。
大致步骤图解(非完整):
void postOrderTree2(BiTree T){
stack<BiTree> S;
BiTNode* p = T;
BiTNode* r = NULL;
while(p||!S.empty()){
if(p){
S.push(p);
p = p->lchild;
}else{
p = S.top();
if(p->rchild&&p->rchild!=r){
p = p->rchild;
}else{
p = S.top();
S.pop();
printf("%c ",p->data);
r = p;
p = NULL;
}
}
}
}
层序遍历:
将树分为一层又一层,按照层次遍历树中的结点。
可以使用队列这个数据结构来实现:
大致的遍历步骤(非完整):
void LevelOrder(BiTree T){
queue<BiTNode*> Q;
BiTNode* p = T;
if(!T){
return;
}
Q.push(p);
while(!Q.empty()){
p = Q.front();
Q.pop();
printf("%c ",p->data);
if(p->lchild){
Q.push(p->lchild);
}
if(p->rchild){
Q.push(p->rchild);
}
}
}