码迷,mamicode.com
首页 > 其他好文 > 详细

中序线索化二叉树

时间:2016-11-19 23:23:18      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:div   one   stream   pen   线索   end   cte   str   name   

  中序线索化二叉树

 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 }
中序线索化二叉树

 

中序线索化二叉树

标签:div   one   stream   pen   线索   end   cte   str   name   

原文地址:http://www.cnblogs.com/log-xian/p/6081730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!