二叉树的建立与遍历
如下图所示,通过输入该完全二叉树的顺序存储结构,程序自动建立该完全二叉树的链式存储结构,并利用链式存储结构实现对该二叉树的先序遍历、中序遍历、后序遍历和层次遍历。
注意:1.程序启动时,由用户输入结点数量,并按顺序输入结点的值
2.先序、中序遍历必须包含非递归实现
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
# define MAXNODE 40
# define MAXSIZE 40
typedef int elemtype;
//定义二叉树结点
typedef struct BiTNode
{
elemtype data;
struct BiTNode * lchild,* rchild;
int index;
}BiTNode,* BiTree;
//定义查看函数
void Visite(elemtype data)
{
printf("\t%d\n",data);
}
typedef BiTree datatype;
//定义顺序存放结点数据的栈
typedef struct
{
datatype data[MAXSIZE];
int top;
int flag;
}SeqStack;
//定义栈初始化函数
SeqStack * Init_SeqStack()
{
SeqStack * s =(SeqStack *)malloc(sizeof(SeqStack));
s->top=-1;
s->flag=0;
return s;
}
//定义判断栈是否为空的函数
int Empty_SeqStack(SeqStack * s)
{
if(s->top==-1)
return 1;
else
return 0;
}
//定义入栈函数
int Push_SeqStack(SeqStack * s,datatype x)
{
if(s->top==MAXSIZE-1)
return 0;
else
{
s->top++;
s->data[s->top]=x;
s->flag=1;
return 1;
}
}
//定义出栈函数
int Pop_SeqStack(SeqStack * s,datatype * x)
{
if(Empty_SeqStack(s)==1)
return 0;
else
{
*x=s->data[s->top];
s->top--;
return 1;
}
}
//定义取栈顶元素函数
datatype Top_SeqStack(SeqStack * s)
{
if(Empty_SeqStack(s)==1)
return 0;
else
return(s->data[s->top]);
}
//定义初始化二叉树函数
//参数bt:根结点的指针变量
//返回值:0--动态内存分配失败 1--初始化成功
int initnate(BiTree *bt,elemtype x)
{
/*初始化建立二叉树bt的头结点*/
if((*bt = (BiTNode *)malloc(sizeof(BiTNode))) == NULL)//判断动态内存是否分配
{
printf("动态内存没有分配!\n");
return 0;
}
(*bt)->data = x;
(*bt)->lchild= NULL;
(*bt)->rchild= NULL;
(*bt)->index = 1;
return 1;
}
//定义一个二叉树左子树插入函数
//参数:bt--根结点指针 x--插入结点的数据 parent--插入位置的指点 index--索引
//返回值:NULL--动态内存没有分配,插入失败 bt--根结点指针
BiTree InsertL(BiTree bt,elemtype x,BiTree parent,int index)
{
/*在二叉树bt的结点parent的左子树插入数据元素x*/
BiTree p;
if(parent == NULL)
{
printf("\n插入出错!\n");
return NULL;
}
//p = (BiTree)malloc(sizeof(BiTNode));
if((p = (BiTree)malloc(sizeof(BiTNode))) == NULL)//判断动态内存是否分配成功
return NULL;
p->data = x;
p->index = index;
p->lchild = NULL;
p->rchild = NULL;
if(parent->lchild == NULL)
{
parent->lchild = p;
}
else
{
p->lchild = parent->lchild;//在parent节点与它的左子树插入一个新的节点
parent->lchild = p;
}
return bt;
}
//定义一个二叉树右子树插入函数
//参数:bt--根结点指针 x--插入结点的数据 parent--插入位置的指点
//返回值:NULL--动态内存没有分配,插入失败 bt--根结点指针
BiTree InsertR(BiTree bt,elemtype x,BiTree parent,int index)
{
/*在二叉树bt的结点parent的右子树插入数据元素x*/
//printf("right\n");
BiTree p;
if(parent == NULL)
{
printf("插入出错!\n");
return NULL;
}
if((p = (BiTree)malloc(sizeof(BiTNode)))== NULL)//判断动态内存是否分配成功
return NULL;
p->data = x;
p->index = index;
p->lchild = NULL;
p->rchild = NULL;
if(parent->rchild == NULL)
{
parent->rchild = p;
}
else
{
p->rchild = parent->rchild;//在parent节点与它的右子树插入一个新的节点
parent->rchild = p;
}
return bt;
}
//定义一个二叉树左子树删除函数
//参数:bt--根结点指针 parent--所要删除结点的指针
//返回值:NULL--删除错误 bt--删除成功,返回根结点指针
int DeleteL(BiTree bt,BiTree parent)
{
/*在二叉树删除结点parent的左子树*/
BiTree p;
if(parent == NULL)//判断所要删除的结点时否为空,或它的左子树是否为空
{
printf("删除错误!\n");
return 0;
}
p = parent->lchild;
parent->lchild = NULL;
free(p);/*当p为非叶子结点时,这样删除仅释放了所删子树根结点的空间*/
/*若要删除子树分支中的结点,需要后面介绍的遍历操作来实现*/
p=NULL;
return 1;
}
//定义一个二叉树右子树删除函数
//参数:bt--根结点指针 parent--所要删除结点的指针
//返回值:NULL--删除错误 bt--删除成功,返回根结点指针
int DeleteR(BiTree bt,BiTree parent)
{
/*在二叉树删除结点parent的右子树*/
BiTree p;
if(parent == NULL||parent->rchild==NULL)//判断所要删除的结点时否为空,或它的左子树是否为空
{
printf("删除错误!\n");
return 0;
}
p = parent->rchild;
parent->rchild = NULL;
free(p);/*当p为非叶子结点时,这样删除仅释放了所删子树根结点的空间*/
/*若要删除子树分支中的结点,需要后面介绍的遍历操作来实现*/
return 1;
}
//定义先序遍历二叉树函数
//参数bt:根结点指针
void NRPreOrder(BiTree bt)
{
/*非递归先序遍历二叉树*/
int i=0;
SeqStack * stack_1=Init_SeqStack();
BiTree p=NULL;
if(bt==NULL)
return;
p=bt;
stack_1->top=0;
while(p!=NULL||stack_1->top!=0)
{
while(p!=NULL)
{
Visite(p->data);//访问结点的数据域
if(Push_SeqStack(stack_1, p)==0)
{
printf("栈溢出!\n");
free(stack_1);
p=NULL;
stack_1=NULL;
return;
}
if(stack_1->top==0)
return;
p = p->lchild;//指针指向p的左子树
}
if(Empty_SeqStack(stack_1)==1)//栈空时结束
{
free(stack_1);
stack_1=NULL;
p=NULL;
return;
}
else
{
Pop_SeqStack(stack_1,&p);
p=p->rchild;//指针指向p的右子树结点
}
}
free(stack_1);
stack_1=NULL;
p=NULL;
return;
}
//定义中序遍历二叉树函数
//参数bt:根结点指针
void NRMidOrder(BiTree bt)
{
/*非递归先序遍历二叉树*/
SeqStack * stack_1=Init_SeqStack();
BiTree p=NULL;
if(bt==NULL)
return;
p=bt;
stack_1->top=0;
while(p!=NULL||stack_1->top!=0)
{
while(p!=NULL)
{
if(Push_SeqStack(stack_1, p)==0)
{
printf("栈溢出!\n");
free(stack_1);
p=NULL;
stack_1=NULL;
return;
}
if(stack_1->top==0)
return;
p = p->lchild;//指针指向p的左子树
}
if(Empty_SeqStack(stack_1)==1)//栈空时结束
{
free(stack_1);
stack_1=NULL;
p=NULL;
return;
}
else
{
Pop_SeqStack(stack_1,&p);
Visite(p->data);//访问结点的数据域
p=p->rchild;//指针指向p的右子树结点
}
}
free(stack_1);
stack_1=NULL;
p=NULL;
return;
}
typedef struct
{
BiTree link;
int flag;
}stacktype;
//定义二叉树后序遍历函数
//参数:bt--根结点
void PostOrder(BiTree bt)
{
if(bt==NULL)
return;
PostOrder(bt->lchild);
PostOrder(bt->rchild);
Visite(bt->data);
}
//定义二叉树查找函数
//参数:bt--根结点指针 x--要查找的结点的数据域
//返回值: NULL--搜索失败 p--要搜索结点的指针
BiTree Search(BiTree bt,int index)
{
int i,memory[MAXNODE];
int top=-1;
BiTree p=NULL;
if(bt==NULL)
{
printf("该二叉树为空!\n");
return NULL;
}
while(index!=1)
{
index=index/2;
top++;
if(top<MAXNODE)
{
memory[top] = index;
}
}
for(i=top;i>=0;i--)
{
if(memory[i]==1)
{
p=bt;
}
if(memory[i]%2==0&&memory[i]>1)
{
p=p->lchild;
}
if(memory[i]%2==1&&memory[i]>1)
{
p=p->rchild;
}
}
return p;
}
//定义删除函数
//参数:bt--根结点指针 n--结点个数
void DeleteBiTree(BiTree bt,int n)
{
int i,index;
BiTree p;
for(i=n;i>=1;i--)
{
index=i;
if(index==1)
{
Visite(bt->data);
free(bt);
bt=NULL;
}
if(index%2==0&&index>1)
{
p=Search(bt , index);
DeleteL(bt, p);
}
if(index%2==1&&index>1)
{
p=Search(bt , index);
DeleteR(bt, p);
}
}
return;
}
//功能菜单
void Menu(void)
{
printf("-----------------------------------------------\n");
printf("\t二叉树的建立与遍历\n");
printf("功能菜单:\n");
printf("\t1.创建二叉树\n");
printf("\t2.各种遍历\n");
printf("\t3.注销并退出功能菜单\n");
printf("-----------------------------------------------\n\n");
}
//递归后序遍历
//参数bt:根结点指针
void PreOrder(BiTree bt)
{
if(bt==NULL)
{
return;
}
Visite(bt->data);
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
//定义层次遍历参数
//参数:bt--根结点指针 n--二叉树的结点数
void LevelTraver(BiTree bt,int n)
{
int i;
int index;
BiTree p=bt;
for(i=1;i<=n;i++)
{
index=i;
if(index==1)
{
Visite(bt->data);
}
if(index%2==0&&index>1)
{
p=Search(bt , index);
printf("\t%d\n",p->lchild->data);
}
if(index%2==1&&index>1)
{
p=Search(bt , index);
printf("\t%d\n",p->rchild->data);
}
}
return;
}
//定义创建二叉树函数
//参数:val--指向顺序存储数据的指针,n--二叉树的结点数
//返回值:NULL--创建二叉树失败 bt--二叉树的根结点指针
BiTree CreateBiTree(elemtype * val,int n)
{
int i;
BiTree bt=NULL;
BiTree p=NULL;
int index;
for(i=0;i<n;i++)
{
index=i+1;
if(index==1)
{
if(initnate(&bt,val[i])==0)
{
printf("动态内存分配失败!\n");
return NULL;
}
p=bt;
}
if(index%2==0&&index>1)
{
p=Search(bt , index);
InsertL(bt , val[i] , p , index);
}
if(index%2==1&&index>1)
{
p=Search(bt , index);
InsertR(bt , val[i] , p , index);
}
}
return bt;
}
int main()
{
int i,n,op;
BiTree parent=NULL;
BiTree bt=NULL;
while(1)
{
Menu();
printf("请输入你的选择:");
scanf("%d",&op);
switch(op)
{
case 1:
{
printf("请输入你要创建二叉树的结点树:");
scanf("%d",&n);
elemtype * val=(elemtype *)malloc(sizeof(elemtype) * n);
for(i=0;i<n;i++)
{
printf("请输入第%d个结点的数据:",i+1);
scanf("%d",&val[i]);
}
bt=CreateBiTree(val,n);
break;
}
case 2:
printf("层次遍历:\n");
LevelTraver(bt,n);
printf("后序遍历:\n");
PostOrder(bt);
printf("先序遍历:\n");
NRPreOrder(bt);
printf("中序遍历:\n");
NRMidOrder(bt);
break;
case 3:
DeleteBiTree(bt, n);
printf("菜单已关闭!\n");
return 0;
default:
printf("输入错误!\n");
break;
}
}
}