您的位置:首页 > 其它

线索二叉树

2015-06-26 10:43 316 查看
一、线索二叉树的建立:n个结点的二叉链表中含有n+1个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前趋和后继结点的指针(这种附加的指针称为"线索")。这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。

为了记录节点的前趋和后继,可在原来的二叉树链表中增加一个前趋指针域和一个后继指针域。

这样线索链表中的节点结构为:

ltag:左线索标志。

rtag:右线索标志。

lchildltagdatarchildrtag
ltag
0lchild是指向节点左孩子的指针
1lchild是指向节点前趋的左线索
rtag
0rchild是指向节点左孩子的指针
1rchild是指向节点后继的右线索
设*p是正在遍历的节点,*pre是刚刚遍历过得节点:

1、若节点*p有空指针域,则将其线索标志设置为1。

2、若节点*p有中序前趋节点*pre(*pre!=NULL),则:

(1):若节点*pre的右线索标志已经建立(pre->rtag=1),则pre->rchild=p;

(2):若节点*p的左线索已经建立(p->ltag=1),则p->lchild=pre;

3、将pre指向刚刚访问过得节点p(p=pre),这样,在下一次访问一个新节点的*p1时候,pre依然为其前趋节点。

struct Bintree
{
char data;
int  rtag,ltag;
struct Bintree *lchild,*rchild;
}Bintree;
void Thread(Bintree *root)
{
Bintree *pre;
if(!root)
{
Thread(root->lchild);   //左子树线索化
if(root->lchild==NULL)
root->ltag=1;
if(root->rchild==NULL)
root->rtag=1;
if(pre!=NULL)
if(pre->rtag==1)
pre->rchild=root;
if(root->ltag==1)
root->lchild=pre;
}
pre=p;
Thread(root->rchild);  //右子树线索化

}

二、访问线索二叉树

查找某节点p在指定次序下的前趋节点和后继节点。

在中序线索二叉树中:

查找后继节点的算法

1、若p的右子树为空,则p->rchild为右线索,直接指向p的中序后继节点、

2、若p的右子树为非空,则p的中序后继必是其右子树中第一个中序遍历到的节点,也即是从p的右孩子开始沿左指针链向下找,直至找到一个没有左孩子的节点为止。

Bintree* S_Thread_next(Bintree *root)
{
Bintree *s;
if(root->rtag==1)
return root->rchild;
else
{
s=root->rchild;
while(s->ltag==0)
{
s=s->lchild;
}
return s;
}
}

查找前趋节点的算法:

1、若p的左子树为空,则p->rchild为右线索,直接指向p的中序后继节点、

2、若p的左子树为非空,则p的中序后继必是其左子树中第一个中序遍历到的节点,也即是从p的左孩子开始沿左指针链向下找,直至找到一个没有右孩子的节点为止。

Bintree* E_Thread(Bintree *root)
{
Bintree *s;
if(root->ltag==1)
return root->lchild;
else
{
s=root->lchild;
while(s->rtag==0)
{
s=s->lchild;
}
return s;
}
}


三、遍历线索二叉树:

遍历某种次序的线索二叉树,只要从该节点出发,查找节点在该次序下的后继,直至查找到终端节点为止。

中序遍历线索二叉树:

Tra_Thead(Bintree *root)
{
if(!root)
{
while(root->ltag==0)//找中序序列的开始节点
p=p->lchild;
do{
cout<<root->data<<endl;
root= S_Thread_next(root);//查找后继节点
}
while(root!=NULL);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: