创建二叉树的二叉链表存储结构

创建二叉树的二叉链表存储结构_第1张图片

#include
#include
#include

#define MAXLEN 100

typedef char ElemType;
typedef char DataType;

//二叉链表存储结构
typedef struct BiTNode
{
	DataType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*BiTree; //BiTNode为结点类型,BiTree为指向二叉链表结点的指针类型

//栈的数据类型
typedef BiTree QElemType;

//队列的顺序存储,循环队列的数据类型C语言描述

typedef struct
{
	int front;				//指向对头的位置
	int rear;				//指向对尾的下一个元素的位置
	int queueSize;			//队列的容量
	QElemType data[MAXLEN]; //存放对量数据元素的数组;
}SqQueue;

//1.初始化操作
int initSqQueue(SqQueue *LQ)
{
	LQ->front=LQ->rear=0;
	LQ->queueSize=MAXLEN;
	return 1;
}

//2.判断队空
int SqQueueEmpty(SqQueue Q)
{
	if(Q.front==Q.rear)return 1;
	else return 0;
}

//4.得到队头
int SqGetHead(SqQueue Q,QElemType *e)
{
	if(Q.rear==Q.front)return 0;
	*e=Q.data[Q.front];
	return 1;
}

//5.进队列
int SqEnQueue(SqQueue *LQ,QElemType e)
{
	if((LQ->rear+1)%LQ->queueSize==LQ->front) return 0;
	LQ->data[LQ->rear]=e;
	LQ->rear=(LQ->rear+1)%LQ->queueSize;

	printf("after Enqueue %x:front %d,rear %d\n",e,LQ->front,LQ->rear);
	return 1;
}

//6.出队列
BiTree SqDeQueue(SqQueue *LQ,QElemType *e)
{
	if(LQ->front==LQ->rear) return 0;
	*e=LQ->data[LQ->front];
	LQ->front=(LQ->front+1)%LQ->queueSize;
	printf("after Dequeue %x:front %d,rear %d\n",*e,LQ->front,LQ->rear);
}
//创建二叉树的二插链表存储结构,
//以左子树右子树的字符串形式读入的递归算法
//按先序遍历顺序读入每个节点值,创建二叉链表
void crt_tree(BiTree *T)
{
	char ch;
	scanf("%c",&ch);
	if(ch=='#') *T=NULL;
	else
	{
		*T=(BiTree)malloc(sizeof(BiTNode));
		(*T)->data=ch;
		crt_tree(&(*T)->lchild);
		crt_tree(&(*T)->rchild);
	}
}
//读入边创建二叉链表的非递归算法
//根据层次遍历,按从上到下,从左到右的顺序依次输入二叉树的边
//即读入边的信息(father,child,lrflag),其中father表示父结点
//child表示孩子结点,lrflag表示是左孩子还是右孩子,来建立二叉链表

//算法核心:
//1.每读入一条边,生成孩子结点,并作为叶子结点;之后
//将该结点的指针保存在队列中
//2,从对头指针找该结点的双亲结点指针。如果队头不是,出队列,
//直至队头是该结点的双亲节点。再按rlflag值建立双亲结点的左右孩子关系
void Create_BiTree(BiTree *T)
{
	SqQueue Q;
	BiTree p,s,t;
	char fa,ch,lrflag;
	initSqQueue(&Q);
	scanf("%c%c%c",&fa,&ch,&lrflag);
	while(ch!='#')
	{
		p=(BiTree)malloc(sizeof(BiTNode));
		p->data=ch;							//创建孩子结点
		p->lchild=p->rchild=NULL;			//做成叶子结点
		SqEnQueue(&Q,p);
		if(fa=='#') *T=p;					//建根结点
		else
		{
			 SqGetHead(Q,&s);				//取队列头元素
			 while(s->data!=fa)
			 {
				 SqDeQueue(&Q,&t);
				 SqGetHead(Q,&s);
			 }							//在队列中找双亲结点
			 if(lrflag=='0') s->lchild=p; //连接左孩子结点
			 else s->rchild=p;
		}
		scanf("%c%c%c",&fa,&ch,&lrflag);
	}
}

创建二叉树的二叉链表存储结构_第2张图片

读入边信息 队列节点的地址 二叉链表
#A0 20
AB0 20 40
BC1 40 50
CD0 50 80
CE1 50 80 70
DF0 80 70 90
DG1 80 70 90 30
F#0 队空
void preorder(BiTree T)
{
	if(T)
	{
		printf("%c",T->data);
		preorder(T->lchild);
		preorder(T->rchild);
	}
}
void layer(BiTree bt)
{
	BiTree p;
	SqQueue Q;
	initSqQueue(&Q);
	if(bt) SqEnQueue(&Q,bt);
	while(!SqQueueEmpty(Q))
	{
		SqDeQueue(&Q,&p);
		printf("%c\n",p->data);
		if(p->lchild) SqEnQueue(&Q,p->lchild);
		if(p->rchild) SqEnQueue(&Q,p->rchild);
	}
}
void main()
{
	BiTree T1=(BiTree)malloc(sizeof(BiTNode));
	BiTree T2=(BiTree)malloc(sizeof(BiTNode));
	crt_tree(&T1);
//	Create_BiTree(&T2);    //测试有问题,输入格式不知道用啥
	printf("先序遍历:");
//	preorder(T2);
	preorder(T1);printf("\n");
/*	//初始化一个二叉树,其根节点是A,没有左右孩子
	T->data='A';
	T->lchild=NULL;
	T->rchild=NULL;
//	inorder(T);
	printf("\n");

	T->lchild=(BiTree)malloc(sizeof(BiTNode));
	T->lchild->data='B';
	T->lchild->lchild=NULL;
	T->lchild->rchild=NULL;

	T->rchild=(BiTree)malloc(sizeof(BiTNode));
	T->rchild->data='C';
	T->rchild->lchild=NULL;
	T->rchild->rchild=NULL;
//	inorder(T);
	printf("\n");

	T->lchild->lchild=(BiTree)malloc(sizeof(BiTNode));
	T->lchild->lchild->data='D';
	T->lchild->lchild->lchild=NULL;
	T->lchild->lchild->rchild=(BiTree)malloc(sizeof(BiTNode));
	T->lchild->lchild->rchild->data='G';
	T->lchild->lchild->rchild->lchild=NULL;
	T->lchild->lchild->rchild->rchild=NULL;

	T->rchild->lchild=(BiTree)malloc(sizeof(BiTNode));
	T->rchild->lchild->data='E';
	T->rchild->lchild->lchild=NULL;
	T->rchild->lchild->rchild=NULL;
	T->rchild->rchild=(BiTree)malloc(sizeof(BiTNode));
	T->rchild->rchild->data='F';
	T->rchild->rchild->lchild=NULL;
	T->rchild->rchild->rchild=NULL;
*/	printf("层次遍历\n:");
	layer(T1);
}

运行结果
创建二叉树的二叉链表存储结构_第3张图片

(3)由二叉树的遍历序列确定二叉树
①已知二叉树的先序序列和中序序列可唯一确定一棵二叉树,
若ABC是二叉树的先序序列,可画出5棵不同的二叉树
创建二叉树的二叉链表存储结构_第4张图片

void CrtBT(BiTree *T,char pre[],char ino[],int ps,int is,in n)
{
	//pre为二叉树的先序序列,n是序列字符个数
	//ino是二叉树的中序序列
	//ps是先序序列的第一个字符的位置,初值为0
	//is是中序序列的第一个字符的位置,初值为0
	if(n==0) *T=NULL;
	else
	//在中序序列中查询根,k为-1,没有找到,否则k为根在中序序列中的位置
	{
		k=Search(ino,pre[ps]);
		if(k==-1)*T=NULL;
		else
		{
			if(!(*T=(BiTree)malloc(sizeof(BiTNode))))exit(0);
			(*T)->data=pre[ps];   //建立根结点
			if(k==is)(*T)->lchild=NULL;   //没有左子树
			else CrtBT(&(*T)->lchild,pre,ino,ps+1,is,k-is);//创建左子树
			if(k==is+n-1)(*T)->rchild=NULL;    //没有右子树
			else CrtBT(&(*T)->rchild,pre,ino,ps+1,k+1,n-(k-is)-1));//创建右子树
		}
	}
}

②已知二叉树的后序序列和中序序列可唯一确定一棵二叉树,
③已知二叉树的先序序列和后序序列不能确定一棵二叉树,

(4)由原表达式创建儿叉链表
the contents is a little more,descript later…

你可能感兴趣的:(数据结构)