一 实质
遍历二叉树过程中用线索(前驱和后继)取代空指针的的做法
主要是增加俩个指针,pre指针始终指向刚刚访问过的节点,p指针始终指向当前访问的节点其中,*pre是*p的前驱,*p是*pre的后继
三 中序线索化算法:
//将二叉树按中序线索化算法
typedef enum {link,thread} pointertag;//枚举值分别为0,1
typedef struct node
{
datatype data;
pointertag ltag,rtag; //左右标志
struct node *lchild ,*rchild;
}binthrnode;//线索二叉树节点类型
typedef binthrnode *binthrtree;
void inorderthreading(binthrtree p)
{//将二叉树p中序线索化
if(p)//p非空时,当前访问结点是*p
{
inorderthreading(p->lchild);//左子树线索化
//建立正在访问节点的前驱结点之间的线索
t->ltag = (t->lchild)?link:thread;
t->rtag = (t->rchild)?link:thread;
if(pre)
{
if(pre->rtag==thread)
pre->rchild = p;
if(p->ltag==thread)
p->lchid = pre;
}
pre = p;
inorderthreading(t->rchild);//右子树线索化
}
}
算法分析:和中序遍历一样递归过程对每个节点仅做一次访问,因此对于n个节点的二叉树算法复杂度为o(n)
四 前驱和后继的查找
binthrnode *inordersuccessor(binthrnode *p)
{//在中序线索树查找*p的后继
binthrnode *q;
if(p->rtag==thread)
return p->rchlid;//返回其所指的后继
else
q = p->rchild;//从*p的右孩子开始查找
while(q->ltag==link)
q = q->lchild;//左子树为空,沿左链往下查找
return q;
binthrnode *inorderpre(binthrnode *p)
{//在中序线索树中找结点*p的中序前趋,设p非空
binthrnode *q;
if (p->ltag==thread) //*p的左子树为空
return p->lchild; //返回左线索所指的中序前趋
else{
q=p->lchild; //从*p的左孩子开始查找
while (q->rtag==link)
q=q->rchild; //右子树为空时,沿右链往下查找
return q; //当q的右子树为空时,它就是最右下结点
} //end if
}
从上面可以看出,对与非线索二叉树,查找其节点十分困难需要遍历,而线索二叉树加入了前驱和后继之后是这种查找变得简单易行
转载:http://blog.csdn.net/xsf50717/article/details/40106441