实验内容:
自己确定一个二叉树(树结点类型、数目和结构自定)利用顺序结构方法存储,实现树的构造。
源代码:
#include <stdio.h>
# include<string.h>
# include<math.h>
#include<stdlib.h>
#define ClearBiTree InitBiTree
typedef char TElemType;
TElemType Nil=' ';
#define MAXSIZE 100
typedef TElemType BiTree[MAXSIZE];
typedef struct
{
int level,
order;
}position;
typedef int QElemType;
#define MAXQSIZE 5
typedef struct
{
QElemType *base;
int front;
int rear;
}SqQueue;
int InitBiTree(BiTree B)
{
int i;
for(i=0;i<MAXSIZE;i++)
B[i]=Nil;
return 1;
}
void DestroyBiTree()
{
}
int CreateBiTree(BiTree B)
{
int i = 0, l;
char s[MAXSIZE];
printf("请按层序输入结点的值(字符),空格表示空结点,结点数≤%d:\n", MAXSIZE);
printf("例如:abcefgh\n");
gets(s);
l = strlen(s);
for(;i<l;i++)
{
B[i]=s[i];
if(i!=0 && B[(i+1)/2-1] == Nil && B[i] != Nil)
{
printf("出现无双亲的非根结点%c\n",B[i]);
exit(0);
}
}
for(i=l;i<MAXSIZE;i++)
B[i]=Nil;
return 1;
}
int BiTreeEmpty(BiTree B)
{
if(B[0]==Nil)
return 1;
else
return 0;
}
int BiTreeDepth(BiTree B)
{
int i,j=-1;
for(i=MAXSIZE-1;i>=0;i--)
if(B[i] != Nil)
break;
i++;
do
j++;
while(i>=pow(2,j));
return j;
}
int Root(BiTree B,TElemType *e)
{
if(BiTreeEmpty(B))
return 0;
else
{
*e=B[0];
return 1;
}
}
TElemType Value(BiTree B,position e)
{
return B[((int)pow(2,e.level-1) - 1) + (e.order - 1)];
}
int Assign(BiTree B,position e,TElemType value)
{
int i = (int)pow(2,e.level-1) + e.order - 2;
if(value != Nil && B[(i+1)/2-1] == Nil)
return 0;
else if(value == Nil && (B[i*2+1] != Nil || B[i*2+2] != Nil))
return 0;
B[i]=value;
return 1;
}
TElemType Parent(BiTree B,TElemType e)
{
int i;
if(B[0]==Nil)
return Nil;
for(i=1;i<=MAXSIZE-1;i++)
if(B[i]==e)
return B[(i+1)/2-1];
return Nil;
}
TElemType LeftChild(BiTree B,TElemType e)
{
int i;
if(B[0]==Nil)
return Nil;
for(i=0;i<=MAXSIZE-1;i++)
if(B[i]==e)
return B[i*2+1];
return Nil;
}
TElemType RightChild(BiTree B,TElemType e)
{
int i;
if(B[0]==Nil)
return Nil;
for(i=0;i<=MAXSIZE-1;i++)
if(B[i]==e)
return B[i*2+2];
return Nil;
}
TElemType LeftSibling(BiTree B,TElemType e)
{
int i;
if(B[0]==Nil)
return Nil;
for(i=1;i<=MAXSIZE-1;i++)
if(B[i] == e && i%2 == 0)
return B[i-1];
return Nil;
}
TElemType RightSibling(BiTree B,TElemType e)
{
int i;
if(B[0]==Nil)
return Nil;
for(i=1;i<=MAXSIZE-1;i++)
if(B[i]==e&&i%2)
return B[i+1];
return Nil;
}
void Move(BiTree q,int j,BiTree B,int i)
{
if(q[2*j+1] != Nil)
Move(q,(2*j+1),B,(2*i+1));
if(q[2*j+2] != Nil)
Move(q,(2*j+2),B,(2*i+2));
B[i]=q[j];
q[j]=Nil;
}
int InsertChild(BiTree B,TElemType p,int LR,BiTree c)
{
int j,k,i=0;
for(j=0;j<(int)pow(2,BiTreeDepth(B))-1;j++)
if(B[j]==p)
break;
k=2*j+1+LR;
if(B[k] != Nil)
Move(B,k,B,2*k+2);
Move(c,i,B,k);
return 1;
}
int InitQueue(SqQueue *Q)
{
(*Q).base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
if(!(*Q).base)
exit(0);
(*Q).front=(*Q).rear=0;
return 1;
}
int EnQueue(SqQueue *Q,QElemType e)
{
if((*Q).rear>=MAXQSIZE)
{
(*Q).base=(QElemType *)realloc((*Q).base,((*Q).rear+1)*sizeof(QElemType));
if(!(*Q).base)
return 0;
}
*((*Q).base+(*Q).rear)=e;
(*Q).rear++;
return 1;
}
int DeQueue(SqQueue *Q,QElemType *e)
{
if((*Q).front==(*Q).rear)
return 0;
*e=(*Q).base[(*Q).front];
(*Q).front=(*Q).front+1;
return 1;
}
int DeleteChild(BiTree B,position p,int LR)
{
int i;
int k=1;
SqQueue q;
InitQueue(&q);
i=(int)pow(2,p.level-1)+p.order-2;
if(B[i]==Nil)
return 0;
i=i*2+1+LR;
while(k)
{
if(B[2*i+1]!=Nil)
EnQueue(&q,2*i+1);
if(B[2*i+2]!=Nil)
EnQueue(&q,2*i+2);
B[i]=Nil;
k=DeQueue(&q,&i);
}
return 1;
}
int(*VisitFunc)(TElemType);
void PreTraverse(BiTree B,int e)
{
VisitFunc(B[e]);
if(B[2*e+1]!=Nil)
PreTraverse(B,2*e+1);
if(B[2*e+2]!=Nil)
PreTraverse(B,2*e+2);
}
int PreOrderTraverse(BiTree B,int(*Visit)(TElemType))
{
VisitFunc=Visit;
if(!BiTreeEmpty(B))
PreTraverse(B,0);
printf("\n");
return 1;
}
void InTraverse(BiTree B,int e)
{
if(B[2*e+1]!=Nil)
InTraverse(B,2*e+1);
VisitFunc(B[e]);
if(B[2*e+2]!=Nil)
InTraverse(B,2*e+2);
}
int InOrderTraverse(BiTree B,int(*Visit)(TElemType))
{
VisitFunc=Visit;
if(!BiTreeEmpty(B))
InTraverse(B,0);
printf("\n");
return 1;
}
void PostTraverse(BiTree B,int e)
{
if(B[2*e+1]!=Nil)
PostTraverse(B,2*e+1);
if(B[2*e+2]!=Nil)
PostTraverse(B,2*e+2);
VisitFunc(B[e]);
}
int PostOrderTraverse(BiTree B,int(*Visit)(TElemType))
{
VisitFunc = Visit;
if(!BiTreeEmpty(B))
PostTraverse(B,0);
printf("\n");
return 1;
}
void LevelOrderTraverse(BiTree B,int(*Visit)(TElemType))
{
int i=MAXSIZE-1,j;
while(B[i] == Nil)
i--;
for(j=0;j<=i;j++)
if(B[j] != Nil)
Visit(B[j]);
printf("\n");
}
void Print(BiTree B)
{
int j,k;
position p;
TElemType e;
for(j=1;j<=BiTreeDepth(B);j++)
{
printf("第%d层: ",j);
for(k=1; k <= pow(2,j-1);k++)
{
p.level=j;
p.order=k;
e=Value(B,p);
if(e!=Nil)
printf("%d:%c ",k,e);
}
printf("\n");
}
}
int visit(TElemType e)
{
printf("%c ",e);
return 0;
}
int main()
{
int i,j;
position p;
TElemType e;
BiTree B,s;
InitBiTree(B);
CreateBiTree(B);
printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",
BiTreeEmpty(B),BiTreeDepth(B));
i=Root(B,&e);
if(i)
printf("二叉树的根为:%c\n",e);
else
printf("树空,无根\n");
printf("层序遍历二叉树:\n");
LevelOrderTraverse(B,visit);
printf("中序遍历二叉树:\n");
InOrderTraverse(B,visit);
printf("后序遍历二叉树:\n");
PostOrderTraverse(B,visit);
printf("请输入待修改结点的层号 本层序号: ");
scanf("%d%d%*c",&p.level,&p.order);
e=Value(B,p);
printf("待修改结点的原值为%c请输入新值: ",e);
scanf("%c%*c",&e);
Assign(B,p,e);
printf("先序遍历二叉树:\n");
PreOrderTraverse(B,visit);
printf("结点%c的双亲为%c,左右孩子分别为",e,Parent(B,e));
printf("%c,%c,左右兄弟分别为",LeftChild(B,e),RightChild(B,e));
printf("%c,%c\n",LeftSibling(B,e),RightSibling(B,e));
InitBiTree(s);
printf("建立右子树为空的树s:\n");
CreateBiTree(s);
printf("树s插到树B中,请输入树T中树s的双亲结点 s为左(0)或右(1)子树: ");
scanf("%c%d%*c",&e,&j);
InsertChild(B,e,j,s);
Print(B);
printf("删除子树,请输入待删除子树根结点的层号 本层序号 左(0)或右(1)子树: ");
scanf("%d%d%d%*c",&p.level,&p.order,&j);
DeleteChild(B,p,j);
Print(B);
ClearBiTree(B);
printf("清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",
BiTreeEmpty(B),BiTreeDepth(B));
i=Root(B,&e);
if(i)
printf("二叉树的根为:%c\n",e);
else
printf("树空,无根\n");
system("pause");
return 0;
}
程序结果: