线索二叉树的运算
在中根线索树上查找某结点的前趋和后继
(1) 已知 q 结点,找出它的前趋结点。
根据线索树的基本概念,当 q->ltag = 1 时, q->lch 就指向 q 的前趋。当 q->ltag=0 时,表明 q 有左孩子。由中根遍历的规律可知,做为根 q 的前趋结点 ( 或者说以根结点为后继的结点 ) ,它应是中根遍历 q 的左子树时 , 所访问的最后一个结点,即左子树的最右尾结点。请看图 6.12(c) ,结点 B 是 A 的左子树的最右尾结点, B 就是 A 的前趋结点。而 B 的后继指针指向了 A , A 就是 B 的后继结点。若用 p 指针记录 q 的前趋前趋结点,求 q 的前趋结点的算法如下:
ThreNode*inpre(ThreNode *q)
{ ThreNode *p,*r;
if(q->ltag==1)p=q->lch; //找到q的前驱
else{ r=q->lch; //在q的左子树,找最右尾结点
while(r->rtag!=1)r=r->rch;
p=r;
}
returnp;
}
(2) 已知 q 结点,找出它的后继结点。
当 q->rtag = 1 时, q->rch 即指向 q 的后继结点。若 q->rt = 0 ,表明 q 有右孩子,那么 q 的后继应是中序遍历 q 的右子树时 , 访问的第一个结点,即右子树的最左结点。看图 6.12(c) , A 的后继为 F , C 的后继为 H 。若用 p 记录 q 后继结点,算法如下:
ThreNode *ThTree::insucc(ThreNode *q)
{ ThreNode *p,*r;
if(q->rtag==1)p=q->rch;
else{r=q->rch;
while(r->ltag!=1)r=r->lch;
p=r;
}
returnp;
}
在中根线索树上遍历二叉树
遍历某种次序的线索二叉树,只要从该次序下的开始结点开发,反复找到结点在该次序下的后继,直至终端结点。
遍历中序线索二叉树算法:
void ThTree::inthorder()
{ ThreNode *p;
p=root;
if(p!=NULL)
while(p->lch!=NULL)p=p->lch; //查找树的最左结点
cout<<"\n "<<p->data;
while(p->rch!=NULL){p=insucc(p);
cout<<" "<<p->data;
};
}
分析:
① 中序序列的终端结点的右线索为空,所以do语句的终止条件是p==NULL。
② 该算法的时间复杂性为O(n)。因为是非递归算法,常数因子上小于递归的遍历算法。因此,若对一棵二叉树要经常遍历,或查找结点在指定次序下的前趋和后继,则应采用线索链表作为存储结构为宜。
③ 以上介绍的线索二叉树是一种全线索树(即左右线索均要建立)。许多应用中只要建立左右线索中的一种。
④ 若在线索链表中增加一个头结点,令头结点的左指针指向根,右指针指向其遍历序列的开始或终端结点会更方便。
线索二叉树
最新推荐文章于 2025-05-02 22:13:06 发布