二叉树的线索化

来源:互联网 发布:慢走丝统盈编程 编辑:程序博客网 时间:2024/06/05 05:31

在二叉树的二叉链表表示实现的时候,当以二叉树作为存储结构时,只能找到节点的左右孩子信息,不能直接得到结点在任一序列中的前驱和后继信息,只有在遍历过程中才能得到这种信息。我们知道,在n个结点的二叉链表栈必定存在n+1个空链域,因此,可以利用这些空链域来存放这些结点信息。所以作如下规定:若结点右左子树,则其lchild域指向其左孩子,否则令lchild域指向其前驱;若结点有右子树,其rchild域指向其右孩子,否则指向其后继。以这种结构构成的二叉链表叫做线索链表。

  • 线索链表的存储结构
[cpp] view plaincopy
  1. typedef enum {link, thread} pointer_tag;  
  2. typedef struct tnode {  
  3.     elemtype        data;  
  4.     struct tnode        *lchild, *rchild;  
  5.     pointer_tag     ltag, rtag;  
  6. }bithrnode, *bithrtree;  
  • 二叉树的线索化(中序线索化)
[cpp] view plaincopy
  1. int inorder_threading(bithrtree *thrt, bithrtree bt)  
  2. {  
  3.     *thrt = (bithrtree) malloc (sizeof(bithrnode));  
  4.     if (!*thrt)  
  5.         exit(OVERFLOW);  
  6.                                                    /* 将头结点线索化 */  
  7.     (*thrt)->ltag = link;  
  8.     (*thrt)->rtag = thread;  
  9.     (*thrt)->rchild = (*thrt);  
  10.   
  11.     if (!bt)                                     /* 若二叉树为空,则将lchild指向自己 */  
  12.         (*thrt)->lchild = (*thrt);  
  13.     else {  
  14.         (*thrt)->lchild = bt;                   /* 头结点左指针指向根结点 */  
  15.         pre = (*thrt);  
  16.         in_threading(bt);                       /* 中序遍历进行中序线索化 */  
  17.         pre->rchild = *thrt;  
  18.         pre->rtag = thread;  
  19.         (*thrt)->rchild = pre;  
  20.     }  
  21.     return OK;  
  22. }  
[cpp] view plaincopy
  1. void in_threading(bithrtree t)  
  2. {  
  3.     if (t) {  
  4.         in_threading(t->lchild);  
  5.   
  6.         if (!t->lchild) {  
  7.             t->ltag = thread;  
  8.             t->lchild = pre;  
  9.         }  
  10.         if (!pre->rchild) {  
  11.             pre->rtag = thread;  
  12.             pre->rchild = t;  
  13.         }  
  14.         pre = t;  
  15.         in_threading(t->rchild);  
  16.     }  
  17. }  
线索化的实质是将二叉链表中的空指针改为指向前驱或后继的线索,前驱和后继的信息是在遍历过程中才能得到,故线索化的过程即为在遍历过程中修改空指针的过程。
  • 线索二叉树的遍历(中序)
[cpp] view plaincopy
  1. int inorder_traverse_thr(bithrtree thrt, int (*visit)(bithrtree t))  
  2. {  
  3.     bithrtree       p;  
  4.   
  5.     p = thrt->lchild;  
  6.     while (p != thrt) {  
  7.         while (p->ltag == link)  
  8.             p = p->lchild;  
  9.         visit(p);  
  10.   
  11.         while (p->rtag == thread && p->rchild != thrt) {  
  12.             p = p->rchild;  
  13.             visit(p);  
  14.         }  
  15.         p = p->rchild;  
  16.     }  
  17.     return OK;  
  18. }  
  • 总结
在中序线索二叉树上遍历二叉树,时间复杂度任然为O(n)。
原创粉丝点击