中序线索化二叉树

Posted 乐于生活

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中序线索化二叉树相关的知识,希望对你有一定的参考价值。

  中序线索化二叉树

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

 

以上是关于中序线索化二叉树的主要内容,如果未能解决你的问题,请参考以下文章

数据结构1:中序线索化二叉树思考

数据结构与算法__07--前序中序后序线索化二叉树,前序中序后序线索化二叉树遍历(Java语言版本)

中序线索化二叉树

数据结构与算法:树 线索化二叉树(中,前,后序)

无栈非递归中序遍历非线索化二叉树

遍历及线索化二叉树