中序線索化二叉樹


  中序線索化二叉樹

 1 void Tree::_inTree(Node * root, Node * &pre) {
 2     if (root == NULL) {        // 結點為空, 1:二叉樹為空        2:已到達右子樹的最后一個右結點的  rchild
 3         return;
 4     }
 5     _inTree(root->lchild, pre);        // 到達當前結點的左子樹的底部左結點
 6     if (root->lchild == NULL) {
 7         root->ltag = nChild;        // 當前結點 無左孩子, 設置標記為 nChild
 8         root->lchild = pre;            // 設置 lchild 的指針域 為前驅 pre
 9     }    // 注意下列的條件判斷, 要先判斷pre是不是空,再是 pre的其他指針域!
10     if (pre != NULL && pre->rchild == NULL) {    // pre 為上一次訪問過的結點, root為當前結點,通過對 pre的操作,達到線索化,pre位於左子樹是作為前驅,位於右子樹作為后繼
11         pre->rtag = nChild;
12         pre->rchild = root;
13     }
14     pre = root;        // 把 pre 指向當前結點,保存上一次訪問的結點
15     _inTree(root->rchild, pre);
16 }

 

  較為完整可運行程序

  

  1 #include <iostream>
  2 using namespace std;
  3 
  4 enum flag{Child, nChild};
  5 
  6 struct Node {
  7     char data;
  8     Node * lchild;
  9     Node * rchild;
 10     flag ltag, rtag;    // Child 表示是左或右孩子  nChild 表示前驅或后繼
 11 };
 12 
 13 class Tree {
 14 public:
 15     Tree();
 16     ~Tree();
 17     Node * getRoot();
 18     Node * _next(Node *);        // 返回待查找結點的后繼
 19     void Show_inTree(Node *);    // 中序遍歷輸出
 20 private:
 21     Node * root;
 22     Node * Create();        // 供構造函數調用初始化二叉樹
 23     void Delete(Node *);    // 供析構函數析構二叉樹
 24     void _inTree(Node *, Node *&);        // 中序 線索化
 25 };
 26 
 27 int main() {
 28     cout << "以先序方式輸入二叉樹:";
 29 
 30     Tree T;
 31     T.Show_inTree(T.getRoot());
 32 
 33     system("pause");
 34     return 0;
 35 }
 36 
 37 Tree::Tree() {
 38     root = Create();        // 先創建一個默認的二叉樹
 39     Node * pre = NULL;
 40     _inTree(root, pre);        // 再對二叉樹進行線索化
 41 }
 42 
 43 Tree::~Tree() {
 44     while (root->lchild != NULL) {    // 將root,設置為左子樹的最左下角的結點
 45         root = root->lchild;
 46     }
 47     Delete(root);
 48 }
 49 
 50 void Tree::Delete(Node * root) {
 51     if (root->rchild != NULL) {    // 右指針域 是一直指向下一個結點,直到指向為右子樹最右下角的最后結點
 52         Delete(root->rchild);
 53         delete root;
 54     }
 55 }
 56 
 57 Node * Tree::Create() {
 58     Node * root;
 59     char ch;
 60     cin >> ch;
 61     if (ch == '#') {
 62         root = NULL;
 63     } else {
 64         root = new Node();
 65         root->data = ch;
 66         root->ltag = root->rtag = Child;        //  默認設置左右指針域 為孩子
 67         root->lchild = Create();
 68         root->rchild = Create();
 69     }
 70     return root;
 71 }
 72 
 73 void Tree::_inTree(Node * root, Node * &pre) {
 74     if (root == NULL) {        // 結點為空, 1:二叉樹為空        2:已到達右子樹的最后一個右結點的  rchild
 75         return;
 76     }
 77     _inTree(root->lchild, pre);        // 到達當前結點的左子樹的底部左結點
 78     if (root->lchild == NULL) {
 79         root->ltag = nChild;        // 當前結點 無左孩子, 設置標記為 nChild
 80         root->lchild = pre;            // 設置 lchild 的指針域 為前驅 pre
 81     }    // 注意下列的條件判斷, 要先判斷pre是不是空,再是 pre的其他指針域!
 82     if (pre != NULL && pre->rchild == NULL) {    // pre 為上一次訪問過的結點, root為當前結點,通過對 pre的操作,達到線索化,pre位於左子樹是作為前驅,位於右子樹作為后繼
 83         pre->rtag = nChild;
 84         pre->rchild = root;
 85     }
 86     pre = root;        // 把 pre 指向當前結點,保存上一次訪問的結點
 87     _inTree(root->rchild, pre);
 88 }
 89 
 90 Node * Tree::getRoot() {
 91     return root;
 92 }
 93 
 94 void Tree::Show_inTree(Node * root) {
 95     if (root == NULL) {
 96         return;
 97     }
 98     Node * p = root;
 99     while (p->ltag == Child) {    // 索引到左子樹沒有孩子,即中序遍歷中的第一個結點
100         p = p->lchild;
101     }
102     cout << p->data << " ";        // 輸出第一個結點
103     while (p->rchild != NULL) {    // 通過線索化,右孩子為空的時候表示 整個二叉樹訪問完畢
104         p = _next(p);    // 獲取當前結點的后繼,即下一個元素, 注:_next 函數返回的是下一個結點的地址,故此不需要 p = p->rchild;
105         cout << p->data << " ";
106     }
107     cout << endl;
108 }
109 
110 Node * Tree::_next(Node * root) {
111     Node * p = NULL;
112     if (root->rtag == nChild) {        // 右標志為 nChild,無右孩子,直接線索化得到
113         p = root->rchild;
114     } else {                        // 否則是,右孩子的左子樹的最左下結點
115         p = root->rchild;
116         while (p->ltag == Child) {
117             p = p->lchild;
118         }
119     }
120     return p;
121 }
中序線索化二叉樹

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM