《宣州谢朓楼饯别校书叔云》
[唐]李白
弃我去者,昨日之日不可留。
乱我心者,今日之日多烦忧。
长风万里送秋雁,对此可以酣高楼。
蓬莱文章建安骨,中间小谢又清发。
俱怀逸兴壮思飞,欲上青天览明月。
抽刀断水水更流,举杯消愁愁更愁。
人生在世不称意,明朝散发弄扁舟。
前言:
所发布的实验代码尚有功能未完成,其一是不能输入括号,其二是不能对负数进行运算,望博友给予高见,在此不胜感激。
实验要求:
1、 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算
a) 统计叶子结点的个数。
b) 求二叉树的深度。
2、 十进制的四则运算的计算器可以接收用户来自键盘的输入。
3、 由输入的表达式字符串动态生成算术表达式所对应的二叉树。
4、 自动完成求值运算和输出结果。
实验代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<algorithm>
#define maxsize 100//可输入的最大长度
typedef struct BTNode{
double data;//数字型节点
char operate;//运算符型节点
struct BTNode *lchild;
struct BTNode *rchild;
}BTNode,*BiTree;
double cal(BiTree T);
BTNode *calToBiTree(char *input, int s, int e);
int isEmpty(BiTree T);
int BinaryTreeDepth(BiTree T);
int isEmpty(BiTree T);
void menu();
int calDepthOperate(BiTree T);
int calLeafOperate(BiTree T);
int exits();
int main()
{
BiTree T = NULL;
char input[maxsize-1];//保存输入的字符串
int choice = 0,s=0,e;//那么,s似乎没有作用
double result;
while(TRUE){
menu();
scanf("%d", &choice);
switch(choice){
case 1:
printf("请输入需计算的表达式:");
scanf("%s",&input);//读入结果
e=strlen(input);//计算字符串的长度
T = calToBiTree(input, s, e);
result=cal(T);//生成二叉树并计算出结果
printf("计算结果为%lf\n",result);//输出最终结果
break;
case 2:
calLeafOperate(T);
break;
case 3:
calDepthOperate(T);
break;
case 4:
exits();
break;
default:
printf("输入的选择有误!3秒后退出程序\n");
fflush(stdout);
Sleep(3000);
exit(0);
}
}
system("pause");
return 0;
}
//将计算表达式转成二叉树
BTNode *calToBiTree(char *input,int s,int e)
{
int r=0,flag=0,i;
int p=0,q=0,x=0,t;//t为系数
for(i=s;i<e;i++)
if(input[i]=='+'||input[i]=='-'||input[i]=='*'||input[i]=='/')
x++;//判断是否全为数字,如果是x取零,就会直接返回数字
if(!x)
{
int y;
y=input[e-1]-'0';
for(i=e-2,t=1;i>=s;i--)
{
t=10*t;
y=y+t*(input[i]-'0');
}//将该字符串所代表的数字算出
BTNode* bn=(struct BTNode*)malloc(sizeof(struct BTNode));
bn->data=y;
bn->operate=0;
bn->lchild=0;
bn->rchild=0;
return bn;//将该数字的值返回给节点的data中
}
//对括号内的数进行操作
for(i=s;i<e;i++)
{
if(input[i]=='(')
flag++;
else if(input[i]==')')
flag--;//判断该字符是否在括号内,在内flag为1,在外为0
if(!flag)
{
if(input[i]=='*'||input[i]=='/')
p=i;//将括号外的最右侧的*或/号的位置记录下来
else if(input[i]=='+'||input[i]=='-')
q=i;//将括号外的最右侧的+或-号的位置记录下来
}
}
if((p==0)&&(q==0))
calToBiTree(input,s+1,e-1);//去掉最外层的括号
else
{
if(q>0)
r = q;
else if(p>0)
r = p; // 将记录下的+-或*/号记录下来,作为根节点
BTNode* b=(struct BTNode*)malloc(sizeof(struct BTNode));
b->operate=input[r];
b->lchild=calToBiTree(input,s,r);
b->rchild=calToBiTree(input,r+1,e);//对该根节点的左侧和右侧分别再次操作
return b;
}
return NULL;
}
//运算函数
double cal(BiTree T){
if(!T->operate)
return T->data;
switch(T->operate){
case '+':{
return cal(T->lchild)+cal(T->rchild);
break;
}
case '-':{
return cal(T->lchild)-cal(T->rchild);
break;
}
case '/':{
return cal(T->lchild)/cal(T->rchild);
break;
}
case '*':{
return cal(T->lchild)*cal(T->rchild);
break;
}//通过对根节点的运算符的遍历,判断加减乘除并进行操作,最后将结果返回
default:
return 0;
break;
}
return T->data;
}
//判断二叉树是否为空
int isEmpty(BiTree T){
if(T){
return 0;
}
return 1;
}
//计算二叉树的深度
int BinaryTreeDepth(BiTree T){
int lDepth, rDepth;
if(isEmpty(T)){
return 0;
}
else{
lDepth = BinaryTreeDepth(T->lchild);
rDepth = BinaryTreeDepth(T->rchild);
return lDepth > rDepth ? (lDepth + 1) : (rDepth + 1);
}
return 1;
}
//求二叉树叶子结点总数
int leafNodeCount(BiTree T){
if(isEmpty(T)){
return 0;
}
if(!T->lchild && !T->rchild){
return 1;
}
return leafNodeCount(T->lchild) + leafNodeCount(T->rchild);
}
//菜单
void menu(){
printf("请输入您的操作:\n");
printf("1.进行四则运算;\n");
printf("2.计算当前二叉树的叶子节点;\n");
printf("3.计算当前树的深度;\n");
printf("4.退出程序.\n");
}
//操作二:计算叶子结点数
int calLeafOperate(BiTree T){
if(isEmpty(T)){
printf("当前树是一棵空树!\n");
return 0;
}
int leaves = leafNodeCount(T);
printf("当前树的叶子结点数为: %d\n", leaves);
return 1;
}
//操作三:计算树的深度
int calDepthOperate(BiTree T){
int depth = BinaryTreeDepth(T);
printf("当前树的深度为:%d\n", depth);
return 1;
}
//操作四:退出操作
int exits(){
int choose;
printf("您确定要退出程序吗?(输入1退出0返回)\n");
scanf("%d", &choose);
switch (choose)
{
case 1:
printf("三秒后退出程序!\n");
fflush(stdout);
Sleep(3000);
exit(0);
case 0:
return 1;
default:
printf("输入有误,信不信我照样退出程序!\n");
return 0;
}
}
//其实是有两个缺陷的,括号跑不动,负数跑不动
参考文章:
https://blog.csdn.net/qq_42181309/article/details/93867808
https://blog.csdn.net/gaoxiangnumber1/article/details/45053687