线索二叉树
Posted blairgrowing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线索二叉树相关的知识,希望对你有一定的参考价值。
一、线索二叉树的原理
通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。
n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n+1个。如下图所示。
(除根结点以外,所有结点都有一共指向它的结点,所有非空链域为n-1,空链域为n+1)
因此,提出了一种方法,利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。
记ptr指向二叉链表中的一个结点,以下是建立线索的规则:
(1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;
(2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;
显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。结点结构如下所示。
其中:
(1)ltag=0 时指向该结点的左孩子,为1时指向该结点的前驱;
(2)rtag=0 时指向该结点的右孩子,为1时指向该结点的后继;
(3)因此对于上图的二叉链表图可以修改为下图下的样子。
二、线索二叉树结构实现
存储结构
typedef char DataType; typedef enum{Link, Thread}PointerTag; //Link = 0表示指向左右孩子指针;Thread = 1表示指向前驱或后继的线索 struct BitNode{ DataType data; BitNode *lchild, *rchild; PointerTag ltag; PointerTag rtag; }; typedef BitNode* BitTree;
BitTree pre; void InThreading(BitTree p){ if(p){ InThreading(p->lchild);//递归左子树线索化 if (!p->lchild)//没有左孩子 { p->ltag= Thread;//前驱线索 p->lchild=pre;//左孩子指向前驱 } if (!p->rchild)//没有右孩子 { pre->rtag= Thread;//后继线索 pre->rchild=p;//前驱右孩子指向后继 } pre = p; InThreading(p->rchild); } }
int InOrderThraverse_Thr(BiTree t) { BiTree p; p=t->lchild; //p指向根结点 while(p!= t) //空树或遍历结束时p == t { while(p->ltag == Link) //当ltag = 0时循环到中序序列的第一个结点 { p = p->lchild; } cout<<p->data<<" "; //显示结点数据,可以更改为其他对结点的操作 while(p->rtag == Thread && p->rchild != t) { p = p->rchild; cout<<p->data<<" "; } p = p->rchild; //p进入其右子树 } return 0; }
以上是关于线索二叉树的主要内容,如果未能解决你的问题,请参考以下文章