数据结构+二叉遍历算法的应用

一、问题描述

编写一个程序,先用二叉树表示一个简单算术表达式,树的每一个 结点包括一个运算符或运算数。在简单算术表达式中只包含+、-、 *、/和一位正整数且格式正确(不包含括号),并且要按照先乘除后 加减的原则构造二叉树。如图 7.35 所示为“1+2*3-4/5”算术表达 式对应的二叉树。然后由对应的二叉树计算该表达式的值。

二、问题解决

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> typedef struct BTreeNode 
{ char data; struct BTreeNode* lchild; struct BTreeNode* rchild; 
} BTNode; float calculate(BTNode* T) 
{ if(T==NULL) return 0; if(T->data <='9'&&T->data >='0') return (T->data-'0'); //将 char 类型转化为 int 类型进行
计算 else { switch(T->data) //T->data 为运算符,则有左右孩子节
点且不空 { case'+': return calculate(T->lchild) + calculate(T->rchild); 
break; case'-': return calculate(T->lchild) - 
calculate(T->rchild); break; case'*': return calculate(T->lchild) * 
calculate(T->rchild); break;  case'/': return calculate(T->lchild) / 
calculate(T->rchild); break; } } 
} char* input_cheak_str() //字符串动态输入与检测函数 
{ printf("请输入一个简单算术表达式(一位正整数且只有+-*/无括
号):\n"); int ch_num=0; char ch,*str; str=(char*)malloc(sizeof(char)); while((ch=getchar())!='\n') //设置按照输入字符数变化的字符数
组 { if(ch_num%2==1) //下标为奇数,字符应为运算符号 { if(ch!='+' && ch!='-' && ch!='*' && ch!='/') { printf(" 第 %d 个 字 符 输 入 不 合 法 ! 应 为 “ +-*/ ” 之 一
",ch_num+1); return 0; } } else //下标为偶数,字符应该为数字 { if(!(ch>='0' && ch<='9')) { printf("第%d 个字符输入不合法!应为 0 至 9 数字之一
",ch_num+1); return 0; } } str[ch_num]=ch; str=(char*)realloc(str,(++ch_num+1)*sizeof(char)); // ∵
ch_num 为字符数组下标,而 realloc 参数为字符个数 } //∴新
开数组长度参数为下标+2,相当于参数为 num++后的 num+1 if(str[ch_num-1]=='+' || str[ch_num-1]=='-' || str[ch_num-1]=='*' || str[ch_num-1]=='/') { //若最
后一个字符为运算符则输入不合法 printf("最后一个字符输入不合法!应为数字!",ch_num+1); return 0; } str[ch_num]='\0'; //串结尾设置串结束符 return str; 
} BTNode* create_tree(char *str) 
{ int itemCount=0,ASCount=0,len=strlen(str),i; //AS 意为 addSub 加减
法,itemCount 为加减项计数,ASCount 为加减符号计数 BTNode **ASItem,**ASSign,*root,*p; //ASItem 指针数组存
放加减项节点指针,ASSign 指针数组存放加减符号节点指针 ASItem=(BTNode**)malloc((len/2+1)*sizeof(BTNode*)); ASSign=(BTNode**)malloc((len/2)*sizeof(BTNode*)); if(str[0]=='\0') //加减项节点数应该
为加减符号数加一.所以 itemCount==ASCount+1 return NULL; for(i=0;i<len/2;i++) //指针数组置空 ASSign[i]=NULL; for(i=0;i<len/2+1;i++) ASItem[i]=NULL; for(i=0;i<len;i++) //读取 str 字符数组 { if(str[i]<='9' && str[i]>='0') { p=(BTNode*)malloc(sizeof(BTNode)); p->data=str[i]; p->lchild=p->rchild=NULL; } else if(str[i]=='+'||str[i]=='-') { ASItem[itemCount++]=p; //将 p 节点放入加减项数组 p=(BTNode*)malloc(sizeof(BTNode)); p->data=str[i]; ASSign[ASCount++]=p; } //将加减符号节点指针放入 ASSign 数组,因有符号节点的孩子必不为空且创建过程不会访问其孩子节点,故无需置空 else //str[i]符号为乘除的情况 { root=(BTNode*)malloc(sizeof(BTNode)); root->data=str[i]; //将*,/作为数据存入根节点数据
域 root->lchild=p; //p 一定为数字或*,/节点(都是已
构造好的) p=(BTNode*)malloc(sizeof(BTNode)); p->data=str[++i]; //此时 p 为当前节点的下一个节
点,此时 str[++i]必为数字,且下一个访问的 str 必为符号 p->lchild=p->rchild=NULL; root->rchild=p; //根节点的右孩子连上此节点 p=root; //整个根节点构造完毕,传入 p } } ASItem[itemCount]=p; ASSign[0]->lchild=ASItem[0]; //第一个符号节点左孩子连第一
个项节点 ASSign[0]->rchild=ASItem[1]; for(i=1;i<ASCount;i++) //以加减法符号节点作为子树根
节点,加减法之间的项的节点为子树根节点的孩子节点 { ASSign[i]->lchild=ASSign[i-1]; //除第一个节点以外的加减符号
节点左孩子都连上一个符号节点 ASSign[i]->rchild=ASItem[i+1]; //右孩子都连项节点 } return ASSign[ASCount-1]; } void disp_tree(BTNode *T) { if(T != NULL) { printf("%c", T->data); if(T->lchild != NULL || T->rchild != NULL) { printf("("); // 有孩子结点时才输出( disp_tree(T->lchild); // 递归处理左子树 if(T->rchild != NULL) // 有右孩子结点时才输出,  printf(","); disp_tree(T->rchild); // 递归处理右子树 printf(")"); // 有孩子结点时才输出) } } } int main () 
{ char *str=input_cheak_str(); disp_tree(create_tree(str)); printf("\n"); printf("%3.2f",calculate(create_tree(str))); return 0; 

三、代码分析

实现简单算术表达式求值,首先要判断输入的表达式是否合法,即只包含 +、-、*、/且正整数的位数为一位。 构建二叉树算法主体思路是将正确(输入时经过检测)的一位正整数无括 号的简单表达式字符串,以加减法为分界线(因为会先计算乘除法)将表达式分 割成若干个加减项后再将已生成的加减项节点与加减符号项节点交替连接成 树,其中每个加减项节点都是其子树。 计算简单算术表达式的值则是要将 char 类型的数字转化为 int 类型的数 字,然后利用 switch 语句进行加减乘除的运算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399755.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聚合平台项目优化(门面模式,适配器模式,注册器模式)

前言&#xff1a; 这篇文章的思路就是抛出问题&#xff0c;再思考解决方案&#xff0c;最后利用设计模式解决问题 项目背景&#xff1a; 聚合搜索平台的主要功能就是一个有强大搜索能力的一个项目 用户输入一个词&#xff0c;同时可以搜索出用户&#xff0c;文章和图片这种…

AI绘画: ComfyUI奥运高光时刻海报工作流,工作流拆解~

前言 点关注不迷路&#xff01; 这两天&#xff0c;阿里云的PAI ArtLab的ComfyUI新增了一个奥运高光时刻海报的工作流&#xff0c;小编测试下来&#xff0c;效果真的不错。不愧是大厂出品&#xff0c;必属精品。那么这次小编就简单梳理一下这个工作流的的各个部分&#xff0c…

基于vue框架的CKD电子病历系统nfa2e(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;患者,医生,药品信息,电子病历,临时医嘱,长期医嘱,健康科普 开题报告内容 基于Vue框架的CKD电子病历系统 开题报告 一、选题背景 随着信息技术的飞速发展和医疗信息化的深入推进&#xff0c;电子病历系统&#xff08;Electronic Medic…

分布式文件系统FastDFS入门

文章目录 一.分布式文件系统简介&#xff1a;二.FastDFS简介三.FastDFS组成Tracker ServerStorage Serverclient上传流程下载流程文件ID 四.FastDFS配置1.tracker.conf2.stroage 配置文件3.client配置文件 五.FastDFS使用六.代码实现通过execl调用客户端程序进行上传下载使用AP…

如何使用 Puppeteer 和 Node.JS 进行 Web 抓取?

什么是 Headlesschrome&#xff1f; Headless&#xff1f;是的&#xff0c;这意味着这个浏览器没有图形用户界面 (GUI)。不用鼠标或触摸设备与视觉元素交互&#xff0c;你需要使用命令行界面 (CLI) 来执行自动化操作。 Headlesschrome 和 Puppeteer 很多网页抓取工具都可适用…

成功解决7版本的数据库导入 8版本数据库脚本报错问题

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

访问网站显示不安全打不开怎么办如何处理

当访问网站时浏览器提示“不安全”&#xff0c;这通常是由于多种原因造成的。下面是一些常见的原因及其解决办法&#xff1a; 未启用HTTPS协议 如果网站仅使用HTTP协议&#xff0c;数据传输没有加密&#xff0c;会被浏览器标记为“不安全”。解决办法是启用HTTPS协议&#xff…

一篇文章教会你如何使用Haproxy,内含大量实战案例

1. Haproxy 介绍 HAProxy是法国开发者 威利塔罗&#xff08;Willy Tarreau&#xff09; 使用C语言编写的自由及开放源代码软件&#xff0c;是一款具备高并发&#xff08;万级以上&#xff09;、高性能的TCP和HTTP应用程序代理. HAProxy运行在当前的硬件上&#xff0c;可以支持…

5款在线伪原创改写软件,智能改写文章效果好

在这个信息爆炸的时代&#xff0c;内容创作变得愈发重要&#xff0c;而对于创作者来说&#xff0c;有时需要一些得力的伪原创改写工具来辅助我们更好地改写出高质量的内容。今天我要和大家分享5款令人惊喜的在线伪原创改写软件&#xff0c;它们以出色的智能改写效果&#xff0c…

【Kubernetes】身份认证与鉴权

一&#xff0c;认证 所有 Kubernetes 集群有两类用户&#xff1a;由Kubernetes管理的ServiceAccounts(服务账户)和(Users Accounts)普通账户。 两种账户的区别&#xff1a; 普通帐户是针对(人)用户的&#xff0c;服务账户针对Pod进程普通帐户是全局性。在集群所有namespaces…

【Ai学习】一个技巧,解决99%Comfyui报错!

前言 comfyui以极高灵活度及节点化工作流&#xff0c;深受AI绘画者追捧&#xff0c;每当新的模型开源&#xff0c;comfyui都是最先进行适配。 comfyui高度兼容性及灵活性带来丰富强大的扩展&#xff08;插件&#xff09;生态&#xff0c;同时也带来一系列插件安装的问题&…

从今年的计算机视觉比赛看风向

记第一次参加CV比赛的经历-长三角&#xff08;芜湖&#xff09;人工智能视觉算法大赛-CSDN博客 去年参赛的记录里说了&#xff1a; 最近&#xff0c;同样的由芜湖举办的比赛又上线了&#xff0c;果然&#xff1a; 2023年是这些赛题&#xff0c;典型的CV&#xff1a; 今年变成…

阴阳脚数码管

1.小故事 最近&#xff0c;我接到了一个既“清肺”又“烧脑”的新任务&#xff0c;设计一个低功耗蓝牙肺活量计。在这个项目中我们借鉴了一款蓝牙跳绳的硬件设计方案&#xff0c;特别是它的显示方案——数码管。 在电子工程领域&#xff0c;初学者往往从操作LED开始&#xff…

【网络】IP的路径选择——路由控制

目录 路由控制表 默认路由 主机路由 本地环回地址 路由控制表的聚合 网络分层 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 路由控制表 在数据通信中&#xff0c;IP地址作为网络层的标识&#xff0c;用于指定数据包的目标位置。然而&#xff0c;仅有IP地址并不足以确…

基于LPF改进的反电势观测器+锁相环PLL的永磁无感控制

导读:上期文章介绍的基于EMF+PLL的中高速永磁无感控制,其中决定转速和位置的估算精度的是反电势的获取精度。直接计算法很难保证反电势的估算精度,所以本期文章介绍一种基于LPF的改进型EMF观测器。 一、基于LPF改进的EMF观测器 传统的EMF观测器的表达式为: 注:这里重点强…

01_Electron 跨平台桌面应用开发介绍

Electron 跨平台桌面应用开发介绍 一、Electron 的介绍二、关于 NW.js 和 Electron 介绍三、搭建 Electron 的环境1、准备工作&#xff1a;2、安装 electron 环境3、查看 electron 的版本&#xff0c;electron -v 一、Electron 的介绍 Electron 是由 Github 开发的一个跨平台的…

Oracle事务是怎么练成的

什么是事务 事务是数据库管理系统执行过程的一个逻辑单位&#xff0c;由一系列有限的数据库操作序列构成&#xff0c;事务必须满足‌ACID属性。ACID理论是数据库中最重要的概念之一&#xff0c;分别代表原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consisten…

Django基础知识

文章目录 新建Django项目helloworld关联数据库admin 新建Django项目 创建django-admin startproject project_name 运行 python manage.py runserver 创建app: python manage.py startapp app_name 目录&#xff1a; 配置文件 settings.py 路由配置 urls.py 项目管理 manage.p…

极光流星大爆发

卑微仔广东持续200%含云量&#xff0c;线上观望大家分享的极光与流星共舞的神奇场景。 极光与流星相伴的瞬间&#xff0c;永远震撼于绝美的星空 开始放毒&#xff08;放图放图&#xff09;&#xff08;以下均拍摄于12日晚至13日晨这一时间段&#xff09;&#xff1a; 先驱猎光…

VisionPro二次开发学习笔记10-使用 PMAlign和Fixture固定Blob工具检测孔

使用 PMAlign和Fixture固定Blob工具检测孔 这个示例演示了如何使用 PMAlign 工具和 Fixture 工具来夹持一个 Blob 工具。示例代码将检测支架右上角孔的存在。当点击运行按钮时&#xff0c;将读取新图像。PMAlign 工具运行并生成一个 POSE 作为输出。POSE 是一个六自由度的变换…