#include<stdio.h>
#include<stdlib.h>
#define MAX_TREE_SIZE 100;
#define OK 1
#define False 0;
#define ERROR -1
#define OVERFLOW -1
typedef char TElemType;
typedef int Status;
typedef struct BinTNode
{
TElemType data;
struct BinTNode* lchild, * rchild;
}BinTNode,*BinTree;
/*二叉树的先序遍历算法
1.判断 空树
2.访问根结点
3.访问左子树
4.访问右子树*/
void PreOrderTraverse(BinTree T)
{
if (T == NULL)
return;
printf("%c", T->data);/*访问根结点*/
PreOrderTraverse(T->lchild);/*访问左子树*/
PreOrderTraverse(T->rchild);/*访问右子树*/
}
/*中序遍历
1.判空
2.访问左子树
3.访问根结点
4.访问右子树*/
void InOrderTrverse(BinTree T)
{
if (T==NULL)
return;
PreOrderTraverse(T->lchild);
printf("%c", T->data);
PreOrderTraverse(T->rchild);
}
/*后序遍历
1.判空
2.访问左子树
3.访问右子树
4.访问根结点*/
void PostOrderTraverse(BinTree T)
{
if (T == NULL)
return;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c", T->data);
}
void CreateBiTree(BinTree* T)
{
TElemType ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BinTree)malloc(sizeof(BinTNode));
if (!*T)
exit(OVERFLOW);
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
//线索二叉树
typedef enum { Link, Thread }PonterTag;
/*Link=0表示指向左右孩子指针*/
typedef struct BinThrNode
{
TElemType data;
struct BinThrNode* lchild, * rchild;/*左右孩子指针*/
PonterTag Ltag;
PonterTag Rtag;/*左右标志*/
}BiThrNode,*BinThrTree;
BinThrTree pre;/*全局变量,始终指向刚刚访问过的结点*/
/*中序遍历进行中序线索化*/
void InThreading(BinThrTree p)
{
if (p!=NULL)
{
InThreading(p->lchild);/*递归左子树*/
if (!p->lchild)/*没有左子树*/
{
p->Ltag = Thread;/*前驱线索*/
p->lchild = pre;/*左子树指针指向前驱*/
}
if(!pre->rchild)/*前驱没有右子树*/
{
pre->Rtag = Thread;/*后继线索*/
pre->rchild = p;/*前驱右孩子指针指向后继(当前结点p)*/
}
pre = p;
InThreading(p->rchild);/*递归右子树实现线索化*/
}
}
//1
/*在二叉树线索链表上添加一个头结点,并令中序遍历的第一个结点的lchild指针和最后一个结点的rchild指针均指向头结点
这样定义的好处就是我们既可以从第一个结点起顺后继进行遍历,也可以从最后一个结点起顺前驱进行遍历*/
//2
/*T指向头结点,头结点左链lchild指向根结点,头结点右链rchild指向中序遍历的
最后一个结点。中序遍历二叉树线索表表示的二叉树T*/
Status InOrderTraver_Thr(BinThrTree T)
{/*对链表进行扫描,时间复杂度为O(n)*/
BinThrTree p;
p = T->lchild;/*p指向根结点*/
//因为这种线索表的最后结点指向头结点T,所以当p==T时,表示遍历已经结束,或者只有有个头结点
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;
/*线索表充分利用了空指针域的空间,这相当于节省了空间,
又保障了创建时的一次遍历就可以终生受用前驱后继的信息,这意味着节省了空间
多用在需要经常遍历或者查找结点是需要某种遍历序列中的前驱后继*/
}
数据结构-二叉树的创建,遍历,线索化及其遍历线索二叉树
最新推荐文章于 2023-04-12 21:12:45 发布