树和二叉树的应用.docx
- 文档编号:3917706
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:12
- 大小:38.18KB
树和二叉树的应用.docx
《树和二叉树的应用.docx》由会员分享,可在线阅读,更多相关《树和二叉树的应用.docx(12页珍藏版)》请在冰豆网上搜索。
树和二叉树的应用
数据结构实验报告
实验题目:
树和二叉树的应用
实验内容:
重言式判别
实验目的:
掌握树和二叉树的概念及工作原理,运用其原理及概念完成上述实验题中的内容。
实验要求:
为了使学生更好的掌握与理解课堂上老师所讲的概念与原理,实验前每个学生要认真预习所做的实验内容及编写源程序伪码(写在纸上及盘中均可)以便在实验课中完成老师所布置的实验内容。
设计原理:
1.一个逻辑表达式如果对于其变元的任一种取值均为真,则成为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,然而,更多的情况下,既非重言式,也非矛盾式。
写一个程序通过真值表判别一个逻辑表达式属于上述哪一类。
基本要求如下:
(1)逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括“|”、“&”和“~”,分别表示或、与和非,运算优先程度递增,但可有括号改变,即括号内的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
(2)若是重言式或矛盾式,可以只显示“TrueForever”或“FalseForever”,否则显示“Statisfactible”以及变量名序列,与用户交互。
若用户对表达式变元取定一组值,程序就求出并显示逻辑表达式的值。
(3)本程序先使用栈将逻辑表达式的变量进行存储,然后将栈中的元素作为二叉树的结点结构,然后根据优先级读取表达式建立二叉树,并通过逐个判断根实现对重言式的判别。
2.程序执行的命令
(1)输入逻辑表达式
(2)判断表达式是重言式还是矛盾式(3)若既不是重言式也不是矛盾式,则对变元取定值,并显示逻辑表达式的值(4)结束
3.测试数据
(1)(A|~A)&(B|~B)
(2)(A&~A)&C
(3)A|B|C|D|E|~A
(4)A&B&C&~B
(5)(A|B)&(A|~B)
(6)A&~B|~A&B;
输出结果
TrueForever
FalseForever
TrueForever
FalseForever
Statisfactible
Statisfactible
4.本程序主要分为六个模块
(1)主程序模块
voidmain()
{初始化
While{
接受命令
处理命令}
if(choice==0)退出
}
(2)对栈的操作模块。
(3)二叉树的建立模块,采用自底向上根据运算符地优先级来建立子树函数,读取逻辑表达式。
(4)逻辑运算符的优先级判别模块。
(5)重言式的识别函数模块。
(6)求值模块。
5.各个模块之间的调用关系具体如下图:
主函数模块调用:
对操作符栈和变量栈的操作模块initstack()pop()push()geittop(),逻辑运算符的优先级判别模块compa(),二叉树的建立模块creattree(),重言式的判别模块judge(),用户为变量赋值模块user(),求值模块getvalue()。
三.详细程序:
//函数头
#include
#include
#include
#include
//函数状态码定义
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-2
#defineNULL0
typedefintStatus;
#defineinitstackmax100;
typedefstructbittree{
chardata;
bittree*left;//左孩子指针
bittree*right;//右孩子指针
}bittree,*bit;//二叉树类型
structstack{
bit*base;//在栈构造之前和销毁之后,base的值为NULL
inttop;//栈顶指针
intstacksize;//当前已分配的存储空间,以元素为单位
};//栈类型
//其中函数操作的伪码算法如下:
voidinitstack(stack&s)
{//构造一个空栈s
s.base=newbit[100];
s.top=-1;
s.stacksize=initstackmax;
}
voidpush(stack&s,bit&s1)
{
//插入元素s1为新的栈顶元素
s.top++;
s.base[s.top]=s1;
}
chargettop(stack&s)
{
//用s返回栈顶元素
returns.base[s.top]->data;
}
bitpop(stack&s)
{
//删除是栈顶元素,并用s返回其值
s.top--;
returns.base[s.top+1];
}
charcompa(chara,charb)
{
//按优先级的高低顺序输出运算符
charpri[6][7]={
'','|','&','~','(',')','#',
'|','>','<','<','<','>','>',
'&','>','>','<','<','>','>',
'~','>','>','>','<','>','>',
'(','<','<','<','<','=','',
'#','<','<','<','<','','='//第一次进栈时进行比对
};
for(intl=0;l<6;l++)
if(pri[l][0]==a)
break;
for(intj=0;j<7;j++)
if(pri[0][j]==b)
break;
returnpri[l][j];
}
bitcreattree(char*p,stack&vari,stack&symbol)
{
//构造二叉树
initstack(vari);
initstack(symbol);
bitm,n;
bitexam;
exam=newbittree;
exam->data='#';
push(symbol,exam);
while(*p!
='#'||(gettop(symbol)!
='#'))//第一次生成树时,*P!
=#而(gettop()->data=='#')以后则相反
{
if((int(*p)>=65)&&(int(*p)<=90))//是变量
{
exam=newbittree;
exam->data=*p;
exam->left=NULL;
exam->right=NULL;
push(vari,exam);
p++;
}
else
{
switch(compa(gettop(symbol),*p)){
case'<':
exam=newbittree;
exam->data=*p;
exam->left=NULL;
exam->right=NULL;
push(symbol,exam);
p++;
break;
case'=':
exam=pop(symbol);
p++;
break;
case'>':
exam=pop(symbol);
n=pop(vari);
exam->left=n;
exam->right=NULL;
if(exam->data!
='~')
{
m=pop(vari);
exam->right=m;
}
push(vari,exam);
break;
}//switch
}//else
}//while
bittemp=pop(symbol);
deletetemp;
returnexam;
}
intgetvalue(bitroot,intnum[])
{
//根据变量的取值组合并利用逻辑表达式的性质对树进行求值
if((root->data>=65)&&(root->data<=90))
returnnum[root->data-65];
else{
switch(root->data){
case'|':
returngetvalue(root->left,num)||getvalue(root->right,num);
case'&':
returngetvalue(root->left,num)&&getvalue(root->right,num);
case'~':
return!
getvalue(root->left,num);
}
}
}
voiduser(bitroot,intm,charb[])
{
//若用户对表达式变元取定一组值,程序就求出并显示逻辑表达式的值
inta[30];intn;
for(intk=0;k<=m;k++)
{
printf("请输入n的值\n");
scanf("%d",&n);
a[b[k]-65]=n;
}
if(getvalue(root,a))
printf("True");
else
printf("False");
}
voidjudge(bitroot,charbo[],intnu)
{
//重言式的判别
intsample[30];charbl[20],t;intm=0,lzq,value,count=0,tu=0,fa=0,sat=0;
for(intk=0;k if(bo[k]>=65&&bo[k]<=90) { intmark=0; for(intj=0;j if(bl[j]==bo[k]){ mark=1;break; } if(mark==0){ bl[m]=bo[k]; m++; } } intnumall=(int)pow(2,m); m--; for(inti=0;i {lzq=m; for(intj=0;j { sample[bl[lzq]-65]=(i>>j)%2; lzq--; } value=getvalue(root,sample); if(value) { tu++; if(fa>0){ printf("satisfactible"); sat=1; break; } if(tu==numall){ printf("Tureforever\n"); } } else {fa++; if(tu>0){ printf("satisfactible\n"); sat=1; break; } else{ if(fa==numall) printf("Falseforever\n"); } } } if(sat==1){ printf("请给变量赋值,c代表继续,e代表停止"); scanf("%c",&t); while(t){ if(t=='c') { for(i=0;i<=m;i++) printf("%c",&bl[i]); user(root,m,bl); } else break; } } } //3.主函数 intmain(intargc,char*argv[]) { charstr[300],str1[100],*p;intn,len=0,j;intk=0,m,count=0; stackvari,symbol; bitroot; printf("请输入0或1,0--终止程序1--继续程序\n"); scanf("%d",&m); while(m) { count++; if(m==1) { if(count>1)delete[]vari.base; k=0; printf("请输入表达式(变量以大写形式输入)"); gets(str); len=strlen(str); for(j=0;j if(str[j]! ='') { str1[k]=str[j]; k++; } str1[k]='#'; len=strlen(str1); p=str1; root=creattree(p,vari,symbol); judge(root,str1,len); } else { if(count>1)delete[]vari.base; break; } } return0; } 问题及解决方法: 1.开始时,将栈中元素作为二叉树的结点结构很是复杂,建立二叉树后,只需按照遍历逐个进行判断即可顺利实现重言式的判别。 2.模块设计包括结构体模块,操作算法模块和主函数模块,操作算法模块主要包括了栈和树的函数。 3.本程序先使用栈将逻辑表达式的变量进行存储,然后将栈中的元素作为二叉树的结点结构,然后根据优先级读取表达式建立二叉树,并通过逐个判断根实现对重言式的判别,实现时调试顺利。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 应用