二叉樹的遍歷和線索線索二叉樹
阿新 • • 發佈:2018-12-25
一、二叉樹的遍歷
1.先序遍歷在二叉樹非空的情況下:
(1)訪問根結點
(2)先序遍歷左子樹
(3)先序遍歷右子樹
對應演算法如下:
void PreOrder(BiTree T){
if(T != NULL){
visit(T);//訪問根結點
PreOrder(T->lchild);//遍歷右子樹
PreOrder(T->rchild);//遍歷左子樹
}
}
2.中序遍歷
(1)中序遍歷左子樹
(2)訪問根結點
(3)中序遍歷右子樹
對應演算法如下:
void InOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild);
visit(T);
PreOrder(T->rchild);
}
}
3.後序遍歷過程為:
(1)中序遍歷左子樹
(2)中序遍歷右子樹
(3)訪問根結點
對應演算法如下:
void PostOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild);
PreOrder(T->rchild);
visit(T);
}
}
4.由遍歷序列構造二叉樹
根據先序序列和中序序列可唯一確定一棵二叉樹
根據後序序列和中序序列也可以確定一棵二叉樹
但是後序和先序序列無法唯一確定一棵二叉樹
二、線索二叉樹
1.基本概念
若無左子樹,令lchild指向前驅結點,若無右子樹,令rchild指向後繼結點。前繼和後繼根據遍歷序列方式而不同
線索二叉樹儲存結構描述:
typedef struct _node_{
int data;//資料
struct _node_ *lchild, *rchild;//左右孩子指標
int ltag,rtag;//左右線索標誌
}Node;
2.線索二叉樹構造
通過中序遍歷對二叉樹線索化演算法:
主演算法如下:void InThred(ThreadTree &p,ThreadTrdd &pre){ if(p != NULL){ InThread(p->lchild, pre);//遞迴,線索化左子樹 if(p->lchild == NULL){ //左子樹為空,建立前戲線索 p->lchild = pre; p->ltag = 1; } if(pre != NULL && pre->rchild == NULL){ pre->rchild = p; //建立前驅結點的後繼線索 pre->rtag = 1; } pre = p; //標記當前結點成為剛剛訪問過的結點 InThred(p->rchild, pre); //遞迴線索化右子樹 } }
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){
InThread(T, pre);
pre->rchild = NULL;//處理遍歷的最後一個結點
pre->rtag = 1;
}
}
3.線索二叉樹的遍歷(1)找中序二叉樹中中序序列下的第一個結點
ThreadNode *Firstnode(ThreadNode *p){
while(p->ltag == 0) p = p->lchild;
return p;
}
(2)找中序序列二叉樹結點p在中序序列下的後繼結點
ThreadNode *Nextnode(ThreadNode *p){
if(p->rtag == 0)return Firstnode(p->p->rchild);
else return p->rchild;
}
(3)利用以上兩個演算法,寫出中序線索二叉樹的中序遍歷演算法
void Inorder(ThreadNode *T){
for(ThradNode *p=Firstnode(T); p!=NULL; p=Nextnode(p))
visit(p);
}