线索二叉树的构造
//构造大致过程
//pre 进来的时候初始化为NULL
void Threadify(Bitree p,Bitree pre)//无论如何,我们要不断地变换当前节点来达到遍历的效果
{
if(p)
{
Threadify(p->left,pre);//当到了叶节点的时候就开始处理前继和后继与当前节点的关系
if(!p->left)
{
p->Ltag=thread;
p->left=pre; //第一个到达的叶节点自然没有前继,所以Left->NULL
}
if(!pre->right)
{
pre->Rtag=thread;
pre->right=p;
}
pre=p; //在第一个叶节点上插上pre 的旗子,然后改变方向继续行驶遍历
Treadify(p->right,pre)
}
}
排序树节点删除
bool Delete(Bitree *p)
{
Bitree p,s;
if((*p)->left==NULL)//左子树为空则重新连接他的右子树
{
p=*q;(*q)=(*q)->right;free(p);
}
else if((*p)->right==NULL)
{
p=*q;(*q)=(*q)->left;free(p);
}
else//当左右子树不为空时,我们需要三个角色,探险者s,记录者q,和守护者(*p)
{
p=*p;
s=(*p)->left;//因为排序树的特点,只需在left tree 中找到一个能替代(*p)的叶节点就行
while(s->right)
{
p=s;
s=s->right;
} //s 探险者一直先前直到到了没有right 的节点,p 总是在记录s之前的一个节点
(*p)->data=s->data;
if(q!=(*p))
{
q->right=s->left;
}
else
{
q->left=s->left;
}
free(s);
}
}
延后记录
无论是pre 或者是q ,都在充当着一个记录前者状态的一个角色。两个代码中的p,和s,都是充当一个遍历的作用,就像是汽车不断地开过一个又一个的岛,直到开到一个没有左出口的岛的时候。然后进行一些其他的动作,比如插旗(pre=p)或者是改变方向(function(p->right,pre))或是返回。
而两者都是属于延后记录的一种方式,pre ,q 都是在记录s, p跑之前的状态。其实在有序链表插入节点中也有相同的思想
while (ans!=NULL&&ans->data<x)
{
p=ans;
ans=ans->next;
}