由遍历序列确定二叉树
从二叉树的遍历可知,任何一棵二叉树的前序遍历和中序遍历都是唯一的,那么给定结点的前序序列和中序序列能否确定一棵二叉树?
二叉树的前序序列中,第一个结点必定是根D;根节点D可将中序序列分成两部分:D之前是左子树的中序序列,D之后是右子树的中序序列,再根据左子树的中序序列,又可将前序序列除根以外分成左子树的前序序列和右子树的前序序列,以此类推,便可递归得到整棵二叉树。
结论:给定一颗二叉树的前序序列和中序序列,可以唯一的确定一棵二叉树。
二叉树的线索化
线索化是在遍历的过程中修改空指针域的过程。
对二叉树按照不同的遍历次序进行线索化,可以得到先序,中序,后序线索二叉树。
示例
中序线索化算法思路:按照中序遍历的规则,
当访问的节点root root的前驱结点pre
root无左--->prey为root的前驱
root为pre的后继
void Inthread(BiTree root)// 对root所指的二叉树进行中序线索化,其中pre始终指向刚访问过的结点,其初值为NULL{
if(roo!=NULL) Inthread(root->LChild); // 线索化左子树 if(root->LChild==NULL) {
root->Ltag=1;LChild=pre; // 置前驱线索 if(pre!=MULL && pre->RChild==NULL) // 置后继线索 pre->RChild=root;pre->Rtag=1; pre=root; Inthread(root->RChild); // 线索化右子树 }}
线索化之后如何找前驱后继,是线索化的重要作用
1)找结点的中序前驱结点
假设中序遍历序列如下:
问题:P的中序前驱x节点在树中什么位置?
答:x结点应该在p的左子树的“最右下端”。
左子树最后一个被访问的点
void InPre(BiTNode*p,BiTNode*pre)// 在中序线索二叉树中查找p的中序前驱,并用pre指针返回结果{
if(p->Ltag==1) pre=p->LChild; // 直接利用线索 else {
// 在p的左子树中查找“最右下端”结点 for(q=p->LChild;q=Rtag=0;q=q->RChild); pre=q; }}
2)在中序线索数中找结点后继--没有右孩子直接就是后继指针,有右孩子为右子树第一个访问节点
假设中序遍历序列如下
问题:p的中序后继结点x在树中的什么位置?
答:x节点应该在p的右子树的最左下端。
void InSucc(BiTNode*p,BiTNode*succ)// 在中序线索二叉树中查找p的后继结点,并用succ指针返回结