- 线索二叉树(要求掌握中序遍历的代码)
- 树和森林与二叉树的相互转换(要求掌握转换方法)
- 赫夫曼树和赫夫曼编码(要求掌握构建方法)
线索二叉树参考链接
https://blog.csdn.net/qq_39295755/article/details/79535406
typedef struct TBTNode
{
char data;
int ltag,rtag; //线索标记
struct TBTNode *lchild;
struct TBTNode *rchild;
}TBTNode;
//通过中序遍历对二叉树线索化的递归算法
void InThread(TBTNode *p,TBTNode *&pre)
{
if(p!=NULL) //p指向当前结点 pre指向p的前驱结点
{
InThread(p->lchild,pre); //递归,左子树线索化
if(p->lchild==NULL)
{ //建立当前结点的前驱线索
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL && pre->rchild==NULL)
{ //建立当前结点的后继线索
pre->rchild=p;
pre->rtag=1;
}
pre=p; //pre指向当前的p,作为p要指向的下一个结点的前驱结点指示指针
InThread(p->rchild,pre);
/* p=p->rchild;//p指向一个新结点,此时pre和p分别指向的结点形成了一个前驱后继为下一次线索的连接做准备
InThread(p,pre); //递归,右子树线索化 */
}
}
//通过中序遍历建立中序线索二叉树的主程序
void createInThread(TBTNode *root)
{
TBTNode *pre=NULL; //前驱结点指针
if(root!=NULL)
{
InThread(root,pre);
pre->rchild=NULL; //非空二叉树,线索化后处理中序最后一个结点
pre->rtag=1;
}
}
//在以p为根的中序线索二叉树中,中序序列下的第一个结点算法
TBTNode *First(TBTNode *p)
{
while(p->ltag==0)
p=p->lchild; //最左下结点(不一定时叶结点)
return p;
}
//在求中序线索二叉树中,结点p在中序下的后继结点
TBTNode *Next(TBTNode *p)
{
if(p->rtag==0)
return First(p->rchild);
else
return p->rchild;
}
//中序线索二叉树上执行中序遍历算法
void Inorder(TBTNode *root)
{
for(TBTNode *p=First(root);p!=NULL;p=Next(p))
Visit(p);//Visit()是已经定义的访问p所指结点的函数
}
前序线索二叉树及后序线索二叉树
//前序线索二叉树
void preThread(TBTNode *p,TBTNode *&pre)
{
if(p!=NULL)
{
if(p->lchild=NULL)
{
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL)
{
pre->rchild=p;
pre->rtag=1;
}
pre=p;
//在递归入口处有限制条件,左右指针不是线索才能继续递归
if(p->ltag==0)
preThread(p->lchild,pre);
if(p->rtag==0)
preThread(p->rchild,pre);
}
}
void preorder(TBTNode *root)
{
if(root!=NULL)
{
TBTNode *p=root;
while(p!=NULL)
{
while(p->ltag==0)
{
Visit(p);
p=p->lchild;
}
Visit(p);
p=p->rchild;
}
}
}
//后序线索二叉树
void postThread(TBTNode *p,TBTNode *&pre)
{
if(p!=NULL)
{
postThread(p->lchild,pre);
postThread(p->rchild,pre);
if(p->lchild==NULL)
{
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL && pre->rchild==NULL)
{
pre->rchild=p;
pre->rtag=1;
}
pre=p;
}
}