//树
//树的存储结构
//双亲表示法----结构定义
#define MAXTREESIZE 100
typedef int TElemType;//树结点的数据类型,目前暂定为整型
typedef struct PTNode //结点结构
{
TElemType data;//结点数据
int parent;//双亲位置
}PTNode;
typedef struct//树结构
{
PTNode nodes[MAXTREESIZE];//结点数组
int r, n;//根的位置和结点数
}PTree;
//孩子表示法---结构定义
#define MAXTREESIZE 100
typedef struct CTNode //孩子结点
{
int child;
struct CTNode *next;
}*childptr;
typedef struct //表头结构
TElemType data;
childptr firstchild;
}ctbox;
typedef struct//树结构
{
ctbox nodes[MAXTREESIZE];//结点数组
int r, n;//根的位置和结点数
}ctree;
//孩子兄弟表示法---结构定义
typedef struct CSNode
{
TElemType data;
struct CSNode *firstchild, *rightsib;
}CSNode, *CSTree;
//二叉树
//二叉树的存储结构-----二叉链表结点结构定义
typedef struct BiTNode //结点结构
{
TElemType data;
struct BiTNode *lchild, *rchild;//左右孩子指针
}BiTNode, *BiTree;
//遍历二叉树
//前序遍历递归算法
void PreOrderTraverse(BiTree T)
{
if (T == NULL)
return;//返回到调用处a
printf("%c", T->data);//显示结点数据,也可以更改为其他对结点的操作
PreOrderTraverse(T->lchild);//再先序遍历左子树
PreOrderTraverse(T->rchild);//最后先序遍历右子树
}
//中序遍历递归算法
void PreOrderTraverse(BiTree T)
{
if (T == NULL)
return;//返回到调用处a
PreOrderTraverse(T->lchild);//中序遍历左子树
printf("%c", T->data);//显示结点数据,也可以更改为其他对结点的操作
PreOrderTraverse(T->rchild);//最后中序遍历右子树
}
//后序遍历递归算法
void PreOrderTraverse(BiTree T)
{
if (T == NULL)
return;//返回到调用处a
PreOrderTraverse(T->lchild);//后序遍历左子树
PreOrderTraverse(T->rchild);//最后后序遍历右子树
printf("%c", T->data);//显示结点数据,也可以更改为其他对结点的操作
}
//二叉树的建立---二叉链表二叉树
//把前序遍历序列AB#D##C##用键盘挨个输入,即完成了前序遍历序列的建立,其算法如下
//#表示空树,构造二叉链表表示二叉树T
void CreateTree(BiTree *T)
{
TElemType ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BiTree)malloc(sizeof(BiTNode));//创建结点
if (!*T)//存储分配失败
exit(OVERFLOW);
(*T)->data = ch;//生成根节点
CreateBiTree(&(*T)->lchild);//构造左子树
CreateBiTree(&(*T)->rchild);//构造右子树
}
}
//线索二叉树
//线索二叉树结构实现
typedef enum { Link, Thread } PointerTag;//Link==0表示指向左右孩子指针,Thread==1表示指向前驱和后继的线索
typedef struct BiThrNode //二叉线索存储结点结构
{
TElemType data;//结点数据
strcut BiThrNode *lchild, *rchild;//左右孩子指针
PointerTag LTag;
PointerTag RTag;//左右标志
}BiThrNode, *BiThrTree;
//中序遍历线索化的递归函数代码
//线索化的过程就是在遍历的过程中修改空指针的过程
BiThrTree pre;//全局变量,始终指向刚刚访问过得结点
void InThreading(BiThrTree p)
{
if (p)//若p不为空
{
InThreading(p->lchild);//递归左子树线索化
if (!p->lchild)//没有左孩子
{
p->LTag = Thread;//前驱线索
p->lchild = pre;//左孩子指针指向前驱?????Null
}
if (!pre->rchild)//前驱没有右孩子
{
pre->RTag = Thread;//后继线索
pre->rchild = p;//前驱右孩子指针指向后继(当前结点p)
}
pre = p;//保持pre指向p的前驱
InThreading(p->rchild);//递归右子树线索化
}
//中序遍历二叉线索链表表示的二叉树T
//T指向头结点,头结点左链lchild指向根结点,头结点右链rchild指向中序遍历的最后一个结点
Status InOrderTraverse_Thr(BiThrTree T)
{
BiThrThree p;
p = T->lchild;//p指向根结点
while(p != T)//空树或遍历结束时,p==T
{
while (p->LTag == Link)//当Ltag==0时循环到中序序列第一个结点
p = p->lchild;
printf("%c", p->data);//显示结点数据,也可以更改为其他对结点的操作
while(p->RTag == Thread&&p->rchild != T)
{
p = p->rchild;
printf("%c", p->data);
}
p = p->rchild;//p指向其右子树根
}
return OK;
}
//二叉树的应用---哈夫曼树(最优二叉树)
三 树
最新推荐文章于 2022-08-15 10:09:54 发布