#include<stdio.h>
#include<stdlib.h>
#define ENDMARK 0//树叶子结束标志
#define datatype int
typedef enum{link,thread} tagtype;//定义枚举性tagtype
typedef struct treenode//定义树结点结构体
{
datatype num;
struct treenode * lchild;
struct treenode * rchild;
tagtype ltag,rtag;//左右标记位
}treenode,*treeptr;
void creat_tree(treeptr * tree);//前序遍历,建立二叉树
void visit(treeptr tree);//访问结点
void InOrderTranverse(treeptr tree);//中序遍历二叉树
void InOrderThread(treeptr tree,treeptr * pre);//中序线索化
void InOrderThreading(treeptr * thead, treeptr tree);//添加头结点,实现中序线索化,形成循环链表
void InOrderThreading_Tranverse(treeptr thead);//利用非递归的方式遍历二叉树
void main()
{
treeptr t,thead;
creat_tree(&t);
printf("tree not threaded is:\n");
InOrderTranverse(t);
printf("threaded tree is:\n");
InOrderThreading(&thead, t);//添加头结点,实现中序线索化,形成循环链表
InOrderThreading_Tranverse(thead);
system("pause");
}
void creat_tree(treeptr * tree)//前序遍历,建立二叉树
{
datatype temp;
treeptr newnode;
scanf("%d",&temp);
if (temp==ENDMARK)
{
(*tree)=NULL;//结束
return;
}
else
{
newnode = (treeptr)malloc(sizeof(treenode));//创建新结点及结点初值化
newnode->num = temp;
newnode->ltag = link;//初值皆为link
newnode->rtag = link;
*tree = newnode;
creat_tree(&(*tree)->lchild);//遍历左子树
creat_tree(&(*tree)->rchild);//遍历右子树
}
}
void InOrderTranverse(treeptr tree)//中序遍历二叉树
{
if (tree==NULL)
{
return;
}
else
{
InOrderTranverse(tree->lchild);//遍历左子树
visit(tree);
InOrderTranverse(tree->rchild);//遍历左子树
}
}
void visit(treeptr tree)//访问结点
{
printf("%p,%p,%p,%d,%d,%d\n",tree,tree->lchild,tree->rchild,tree->num,tree->ltag,tree->rtag);
}
/*中序线索化二叉树其实就是
将结点中的空指针改为指向
前驱结点或后继结点的指针,
从而将二叉树改为一个循环
链表*/
void InOrderThread(treeptr tree,treeptr * pre)//中序线索化
{
if (tree)
{
InOrderThread(tree->lchild, pre);//遍历左子树,找到该节点的最左边的叶子开始
if(!tree->lchild)
{
tree->lchild=*pre;
tree->ltag = thread;
}
if(!(*pre)->rchild)
{
(*pre)->rchild = tree;
(*pre)->rtag = thread;
}
(*pre)=tree;//当前结点为pre
InOrderThread(tree->rchild, pre);//遍历由子树,找到该节点的最左边的叶子开始
}
}
void InOrderThreading(treeptr * thead, treeptr tree)//添加头结点,实现中序线索化,形成循环链表
{
treeptr newnode,pre;
newnode = (treeptr)malloc(sizeof(treenode));
*thead = newnode;
(*thead)->rchild = (*thead);//指定右孩子,非空
(*thead)->rtag = thread;
(*thead)->ltag = link;
if (!tree)
{
(*thead)->lchild = (*thead);
}
else
{
(*thead)->lchild = tree;//添加头结点
}
pre = (*thead);
InOrderThread(tree, &pre);//中序线索化二叉树
pre->rchild = (*thead);
pre->rtag = thread;
(*thead)->rchild = pre;
}
void InOrderThreading_Tranverse(treeptr thead)//利用非递归的方式遍历线索化后的二叉树
{
treeptr tree;
tree = thead->lchild;
while(tree!=thead)
{
while(tree->ltag==link)
{
tree = tree->lchild;//遍历到该节点下最左边的叶子
}
visit(tree);
while(tree->rtag==thread&&tree->rchild!=thead)//到下一个含有右子树的根节点
{
tree = tree->rchild;
visit(tree);
}
tree = tree ->rchild;//找到右子树叶子
}
}
中序线索化二叉树
最新推荐文章于 2024-05-22 21:00:01 发布