数据结构二叉树运算器实验报告Word下载.docx
《数据结构二叉树运算器实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构二叉树运算器实验报告Word下载.docx(21页珍藏版)》请在冰豆网上搜索。
S,SElemTypee){
if(S.top-S.base>
=S.stacksize){
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREASE)*sizeof(SElemType));
if(!
S.base)
exit
(1);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREASE;
}
*S.top++=e;
}
intPop(SqStack&
S,SElemType&
e){
if(S.base==S.top)
return-1;
e=*--S.top;
return0;
/*====================队列-ADT====================*/
voidInitQueue(LinkQueue&
Q){
Q.front=Q.rear=(Queue)malloc(sizeof(QNode));
if(!
Q.front)exit
(1);
Q.front->
next=NULL;
}//InitQueue
voidEnQueue(LinkQueue&
Q,QElemTypee){
Queuep;
p=(Queue)malloc(sizeof(QNode));
p)exit
(1);
p->
data=e;
Q.rear->
next=p;
Q.rear=p;
}//EnQueue
intDeQueue(LinkQueue&
Q,QElemType&
if(Q.front==Q.rear)
return0;
p=Q.front->
next;
e=p->
data;
next=p->
if(Q.rear==p){
Q.rear=Q.front;
Q.rear->
free(p);
}//DeQueue
/*====================二叉树-ADT====================*/
BiTreePreCreateBiTree(){
BiTreep;
charch;
ch=getchar();
if(ch=='
#'
)returnNULL;
p=(BiTree)malloc(sizeof(BiNode));
data=ch;
lchild=PreCreateBiTree();
rchild=PreCreateBiTree();
returnp;
}//PreCreateBiTree
这是先序扩展序列创建二叉树,主要是递归调用,先赋值给双亲,再进行调用。
voidPostCreateBiTree1(BiTree&
bt){
SqStackS;
InitStack(S);
while
(1){
ch=getchar();
if(ch=='
@'
)
break;
Push(S,NULL);
else{
p=(BiTree)malloc(sizeof(BiNode));
Pop(S,p->
rchild);
lchild);
Push(S,p);
}
Pop(S,bt);
}//PostCreateBiTree1
这是后序扩展序列创建二叉树,序列从左向右输入,以@为结束符。
扫描入栈时,每当遇到字符,则弹出两个栈顶指针最为右孩子和左孩子,直至遇到结束符@。
BiTreePostCreateBiTree2(){
returnNULL;
rchild=PostCreateBiTree2();
lchild=PostCreateBiTree2();
}//PostCreateBiTree2
这也是后序扩展序列创建二叉树,不过是从右向左输入,扫描时,每当遇到#则返回空指针。
还是用递归,先创建右孩子,再创建左孩子。
intPre_InCreate(BiTree&
bt,char*P,char*Q,intn){
inti;
bt=(BiTree)malloc(sizeof(BiNode));
bt->
data=P[0];
if(n==1){
bt->
lchild=NULL;
rchild=NULL;
for(i=0;
i<
n;
i++){
if(Q[i]==P[0])
if(i!
=0){
lchild=(BiTree)malloc(sizeof(BiNode));
lchild->
data=P[1];
Pre_InCreate(bt->
lchild,P+1,Q,i);
else
=n-1){
rchild=(BiTree)malloc(sizeof(BiNode));
rchild->
data=P[1+i];
rchild,P+1+i,Q+1+i,n-1-i);
}//Pre_InCreate
这是用先序和中序序列创建二叉树。
主要通过分析两个序列之间的关系,通过两个序列的头尾指针和结点数,先找到双亲,再找到左右孩子,然后递归调用向下创建。
主要注意结点数的变化。
intIn_PostCreate(BiTree&
data=Q[n-1];
if(P[i]==Q[n-1])
data=Q[i-1];
In_PostCreate(bt->
lchild,P,Q,i);
data=Q[n-2];
rchild,P+i+1,Q+i,n-i-1);
}//In_PostCreate
这是中序和后序序列创建二叉树。
与先序和中序一样,不再多说。
不过用先序和后序应该不能创建,因为会产生多种可能。
voidVisit(TElemTypech){
printf("
%c"
ch);
}//Visit
用来打印data。
intPreRead(BiTreebt){
bt)
Visit(bt->
data);
PreRead(bt->
}//PreRead
先序遍历,先将data打印,再递归调用。
intInRead(BiTreebt){
InRead(bt->
}//InRead
中序遍历,先递归调用左孩子,再打印data,再调用右孩子。
intPostRead(BiTreebt){
PostRead(bt->
}//PostRead
后序遍历,先将左右孩子递归调用,再打印data。
intTierRead(BiTreebt){
LinkQueueQ;
InitQueue(Q);
EnQueue(Q,bt);
while(!
(Q.front==Q.rear)){
DeQueue(Q,p);
Visit(p->
if(p->
lchild)EnQueue(Q,p->
rchild)EnQueue(Q,p->
}//TierRead
按层遍历,运用队列,先将头指针入队,然后首队结点出队打印,每打印一个,其左右孩子入队。
直至队列为空。
intNumber(BiTreebt){
intn1,n2;
bt)return0;
n1=Number(bt->
n2=Number(bt->
return1+n1+n2;
}//Number
求二叉树结点数,递归调用,当头指针为空时,返回0,否则返回1+左孩子结点数+右孩子结点数。
intLeaf(BiTreebt){
intl1,l2;
bt->
lchild&
&
!
rchild)return1;
l1=Leaf(bt->
l2=Leaf(bt->
returnl1+l2;
}//Leaf
求二叉树叶子数,递归调用,若头指针为空时,返回0,若头指针左右孩子为空,则返回1,否则返回左孩子叶子数+右孩子叶子数。
intHeight(BiTreebt){
inth1,h2;
h1=Height(bt->
h2=Height(bt->
return1+(h1>
h2?
h1:
h2);
}//Height
求二叉树的高度,递归调用,当头指针为空时,返回0,否则返回1+(左右孩子中高度最大的)。
intWide(BiTreebt,int*w,intx){
if(bt)
w[x]=w[x]+1;
if(bt->
lchild)
Wide(bt->
lchild,w,x+1);
rchild)
rchild,w,x+1);
}//Wide
求二叉树的宽度,递归调用,先求得其高度,创建一个数组输入,并输入其层数。
若双亲非空w[x]++。
调用其左右孩子。
这样就可以得到每层的宽度,找到最大值就是二叉树的宽度。
voidCopyBiTree(BiTree&
P,BiTreeQ){
BiTreelp,rp;
Q)
P=NULL;
else{
CopyBiTree(lp,Q->
CopyBiTree(rp,Q->
P=(BiTree)malloc(sizeof(BiNode));
P->
data=Q->
lchild=lp;
rchild=rp;
}//CopyBiTree
复制二叉树,仍是递归调用。
从下向上、从左到右创建,当头指针为空时,赋值空指针。
intDestroyBiTree(BiTree&
DestroyBiTree(bt->
rchild){
free(bt);
bt=NULL;
}//DestroyBiTree
销毁二叉树,递归调用。
如果头指针为空,返回。
调用左右孩子,如果左右孩子为空,释放双亲。
开始先判断左右孩子是否非空,程序很长。
经过调整,最后判断,使函数大大缩减了。
intCalculate(BiTreebt){
intl,r;
returnbt->
data-48;
l=Calculate(bt->
r=Calculate(bt->
switch(bt->
data){
case'
+'
:
returnl+r;
-'
returnl-r;
*'
returnl*r;
/'
returnl/r;
}//Calculate
计算二叉树的值,递归调用。
如果左右孩子为空,返回其ASCII码-48,即其实数值。
开始不是在返回时减去48,而是在计算时减去,不好操作,最后改在返回时减去48。
计算左孩子值和右孩子值,根据算数符号返回相应的值。
intRestore(BiTreebt){
if((bt->
data=='
||bt->
)&
(bt->
)){
printf("
("
);
Restore(bt->
)"
Restore(bt->
}//Restore
还原二叉树,利用中序遍历。
如果双亲是*或者/,左孩子是+或-,则在打印左孩子两边加上()。
否则直接打印。
中间打印双亲。
右孩子同理。
/*====================main====================*/
voidmain(){
intn,m,i,j,x,y;
char*p;
char*q;
int*w;
BiTreeS[10];
10;
i++)
S[i]=NULL;
二叉树运算器\n"
说明:
共有十个二叉树备用位置:
0~9.\n菜单:
\n0\t退出\n1\t创建二叉树\n2\t遍历二叉树\n3\t二叉树结点数\n4\t二叉树叶子数\n5\t二叉树高度\n6\t二叉树宽度\n7\t二叉树每层宽度\n8\t复制二叉树\n9\t销毁二叉树\n10\t还原中缀式\n11\t二叉树求值\n"
请输入命令:
"
scanf("
%d"
&
n);
while(n){
switch(n){
case1:
printf("
1.创建方式:
\n
(1)\t扩展先序\n
(2)\t扩展后序(从左到右输入)\n(3)\t扩展后序(从右到左输入)\n(4)\t先序+中序\n(5)\t中序+后序\n请选择("
scanf("
(%d)请选择创建位置:
n);
i);
while
(1){
if(i>
9||i<
0){
printf("
位置选择错误!
请重新选择存储位置(0-9):
scanf("
}
elseif(S[i]){
已占用!
请重新选择存储位置:
else
break;
}
switch(n){
case1:
printf("
(1)请输入扩展先序序列:
S[i]=PreCreateBiTree();
break;
case2:
(2)请输入扩展后序序列(从左到右输入):
PostCreateBiTree1(S[i]);
case3:
(3)请输入扩展后序序列(从右到左输入):
S[i]=PostCreateBiTree2();
case4:
(4)请输入结点数:
x);
p=(char*)malloc(x*sizeof(char));
if(!
q=(char*)malloc(x*sizeof(char));
q)exit
(1);
(4)请输入先序序列:
for(j=0;
j<
x;
j++){
p[j]=getchar();
p[j]=getchar();
(4)请输入中序序列:
q[j]=getchar();
q[j]=getchar();
Pre_InCreate(S[i],p,q,x);
case5:
(5)请输入结点数:
(5)请输入中序序列:
(5)请输入后序序列:
In_PostCreate(S[i],p,q,x);
free(p);
free(q);
1.创建完成.\n"
case2:
2.遍历方式:
\n
(1)\t先序遍历\n
(2)\t中序遍历\n(3)\t后序遍历\n(4)\t按层遍历\n(5)\t全部显示\n请选择("
(%d)请选择遍历位置:
if(!
S[i]){
NULL\n"
pr