資料結構——線索二叉樹(程式碼)
阿新 • • 發佈:2018-11-04
線索二叉樹
C++ 環境codeblocks17 通過
/* 線索二叉樹 @CGQ 2018/10/29 */ #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; #define ElemType char typedef struct BiTNode { ElemType data; struct BiTNode *lchild, *rchild; int LTag,RTag; // Tag 為0表示指向左右孩子,為1表示指向前驅和後繼 }BiTNode, *BiTree; BiTree pre;// 全域性變數pre,記錄節點前驅,初始時指向線索樹的頭節點(非樹根) void CreateBiTree(BiTree &T) {// 先序建立二叉樹 ElemType ch; cin>>ch; if(ch == '#') T = NULL; else { T = new BiTNode; T->data = ch; T->LTag = 0; // 標誌位置0,表示指向左右孩子(可以不要,在InThreading()中賦值) T->RTag = 0; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } } void InThreading(BiTree T) {// 中序線索化 if(T) { InThreading(T->lchild); // 左子樹遞迴線索化 if(!T->lchild) // T的左孩子為空 { T->LTag = 1; // 給T加上左線索 T->lchild = pre; // T的左孩子指向pre(前驅) } else T->LTag = 0; if(!pre->rchild) //pre 的右孩子為空 { pre->RTag = 1; // 給pre加上右線索 pre->rchild = T; // pre的左孩子指向T(後繼) } else pre->RTag = 0; pre = T; InThreading(T->rchild); // 右子樹遞迴線索化 } } void InOrderThreading(BiTree &THead, BiTree T) {// //中序遍歷二叉樹T, 線索化,THead 指向頭節點 THead = new BiTNode; // 建立頭節點 THead->LTag=0; // 頭節點的左孩子指向樹根 THead->RTag=1; // 頭節點有孩子為線索指標 THead->rchild=THead; // 初始化時右指標指向自己 if(!T) THead->lchild=THead; // 樹非空,則左指標也指向自己 else { THead->lchild=T; pre = THead; // 頭節點左孩子指向樹根,pre指向頭節點 InThreading(T); // 中序線索化二叉樹 pre->rchild=THead; // 線索化結束後,pre為最右節點,pre的右線索指向頭節點 pre->RTag=1; THead->rchild=pre; // 頭節點右線索指向最右節點 } } void InOrderTraverse_Thr(BiTree &T) {// 中序遍歷二叉樹,非遞迴 BiTree p = T->lchild; // p指根節點 while(p != T) { while(p->LTag==0) // 沿左孩子一直向下 p=p->lchild; cout<<p->data<<" "; //訪問左子樹為空的節點 while(p->RTag==1&&p->rchild!=T) // 沿著右線索訪問後續節點 { p=p->rchild; cout<<p->data<<" "; } p = p->rchild; // 當p沒有右線索時,轉向p的右子樹 } } int main() { BiTree T=NULL,THead; CreateBiTree(T); // 建立 InOrderThreading(THead,T); // 線索化 InOrderTraverse_Thr(THead); // 遍歷 return 0; } /* 測試資料: AB#CD###EF##HI##G## A / \ B E \ /\ C F H / /\ D I G ABD##E##CF##G## A / \ B C /\ /\ D E F G HDA##C#B##GF##ER##T## */