线索中序二叉树
1.节点的结构
typedef struct node
{
int lefttype;//左孩子类型,如果是普通左孩子则为Link,如果是前驱则为Thread
int righttype;//右孩子类型,如果是普通右孩子则为Link,如果是后继则为Thread
struct node* left;
struct node* right;
int d;
}Node;
1.线索化算法
1.用一个pre指针指向访问当前节点p的前驱节点
2.在访问当前以p为根节点的子树时,如果左子树非空,则线索化左子树,获得左子树访问的最后一个节点pre;如果左子树为空,则将p的左子树类型lefttype置为Thread,p的左孩子指针置为pre。
3.处理完p的左孩子之后,判断pre的右孩子指针的类型,如果为Thread,则将pre的右孩子指针指向p
4.pre更新为p
5.如果p的右孩子指针为空,则将右孩子指针类型置为Thread;如果非空,则线索化右子树,获得右子树访问的最后一个节点pre
6.返回pre
Node* threading_btree(Node* root,Node* pre)
{
if(!root->left)
{
root->lefttype=Thread;
root->left=pre;
}
else
{
pre=threading_btree(root->left,pre);
}
if(pre->righttype==Thread)
pre->right=root;
pre=root;
if(!root->right)
{
root->righttype=Thread;
}
else
{
pre=threading_btree(root->right,pre);
}
return pre;
}
2.线索二叉树创建
1.为了方便,我们在构建二叉树时新加了一个空头节点用于控制访问开始和结束
2.首先建立一个新的头节点thrd,让其lefttype=righttype=Thread,left和right指向本身
3.然后将其指针作为pre,根节点root作为p线索化二叉树
4.获取最后线索二叉树访问的最后一个节点pre,pre右孩子指针为Thread类型,指向thrd;thrd的左孩子指针指向pre
void create_thrdbtree(Node &thrd,Node *root)
{
thrd.d=-1;
thrd.lefttype=Thread;
thrd.righttype=Thread;
thrd.left=&thrd;
thrd.right=&thrd;
if(!root)
return;
thrd.left=threading_btree(root,&thrd);
(thrd.left)->right=&thrd;
}
3.线索二叉树的遍历
1.设置指针p,初始值为根节点root
2.当p不等于thrd指针,如果p有左孩子,向左走到底
3.访问p节点
4.如果p的右孩子是Thread类型,则不断沿着右孩子指针也就是后继指针走,直到p的右孩子指针为Link类型p的右孩子指向thrd节点
5.p更新为p的右孩子指针
void traverse_btree2(Node *root)
{
Node* p=root->right;
while(p!=root)
{
while(p->lefttype==Link)
p=p->left;
cout<<p->d<<' ';
while(p->righttype==Thread&&p->right!=root)
{
p=p->right;
cout<<p->d<<' ';
}
p=p->right;
}
}