中序表达式转换成后序表达式

合集下载

逆波兰表达式、波兰表达式【数据结构与算法】

逆波兰表达式、波兰表达式【数据结构与算法】

逆波兰表达式、波兰表达式【数据结构与算法】逆波兰表达式、波兰表达式【数据结构与算法】1.前缀表达式⼜称波兰式,前缀表达式的运算符位于操作数之前。

⽐如:- × + 3 4 5 62.中缀表达式就是常见的运算表达式,如(3+4)×5-63.后缀表达式⼜称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后,⽐如:3 4 + 5 × 6 -⼈类最熟悉的⼀种表达式1+2,(1+2)3,3+42+4等都是中缀表⽰法。

对于⼈们来说,也是最直观的⼀种求值⽅式,先算括号⾥的,然后算乘除,最后算加减,但是,计算机处理中缀表达式却并不⽅便。

然后我们还需明确⼀些概念,下⾯通过我们最熟悉的中缀表达式画出⼀棵语法树来直观认识⼀下前后缀表达式的⽣成。

以A+B*(C-D)-E*F为例:中缀表达式得名于它是由相应的语法树的中序遍历的结果得到的。

上⾯的⼆叉树中序遍历的结果就是A+B*(C-D)-E*F。

前缀表达式是由相应的语法树的前序遍历的结果得到的。

上图的前缀表达式为- + A * B - C D * E F后缀表达式⼜叫做逆波兰式。

它是由相应的语法树的后序遍历的结果得到的。

上图的后缀表达式为:A B C D - * + E F * -下⾯我们关注两个点:1.如何根据⼀个逆波兰表达式求出运算结果?2.如果将⼀个中缀表达式转换成后缀表达式(逆波兰表达式)⼀.通过逆波兰表达式计算结果我们先看⼀个例⼦...后缀表达式3 4 + 5 × 6 -的计算1.从左⾄右扫描,将3和4压⼊堆栈;2.遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做⽐较),计算出3+4的值,得7,再将7⼊栈;3.将5⼊栈;4.接下来是×运算符,因此弹出5和7,计算出7×5=35,将35⼊栈;5.将6⼊栈;6.最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

从上⾯的过程我们如何编写代码实现呢?可以采⽤⼀个辅助的栈来实现计算,扫描表达式从左往右进⾏,如果扫描到数值,则压进辅助栈中,如果扫描到运算符,则从辅助栈中弹出两个数值参与运算,并将结果压进到栈中,当扫描表达式结束后,栈顶的数值就是表达式结果。

开放大学数据结构2020年考试必备填空题

开放大学数据结构2020年考试必备填空题

1、数据结构按结点间的关系,可分为4种逻辑结构:集合、线性结构、树形结构、图状结构。

2、数据结构中的数据元素存在多对多的关系称为图状结构结构。

3、在一个长度为n的顺序存储结构的线性表中,向第i(1≤i≤n+1)个元素之前插入新元素时,需向后移动n-i+1个数据元素。

4、从长度为n的采用顺序存储结构的线性表中删除第i(1≤i≤n+1)个元素,需向前移动n-i个元素。

5、数据的逻辑结构在计算机中的表示称为物理结构或存储结构。

6、除了第1个和最后一个结点外,其余结点有且只有一个前驱结点和后继结点的数据结构为线性结构,每个结点可有任意多个前驱和后继结点数的结构为非线性结构。

7、算法的5个重要特性是有穷性、确定性、可形性、有零个或多个输入、有零个或多个输出。

8、数据结构中的数据元素存在一对多的关系称树形结构结构。

9、往栈中插入元素的操作方式是:先移动栈顶指针,后存入元素。

10、数据结构中的数据元素存在一对一的关系称为线性结构结构。

11、要求在n个数据元素中找其中值最大的元素,设基本操作为元素间的比较。

则比较的次数和算法的时间复杂度分别为n-1和O(n)。

12、在一个单链表中p所指结点之后插入一个s所指结点时,应执行__s->next=p->next;__和p->next=s;的操作。

13、设有一个头指针为head的单向循环链表,p指向链表中的结点,若p->next= =head,则p所指结点为尾结点。

14、在一个单向链表中,要删除p所指结点,已知q指向p所指结点的前驱结点。

则可以用操作q->next=p->next; 。

15、设有一个头指针为head的单向链表,p指向表中某一个结点,且有p->next= =NULL,通过操作p->next=head;,就可使该单向链表构造成单向循环链表。

16、每个结点只包含一个指针域的线性表叫单链表。

17、线性表具有顺序存储和链式存储两种存储结构。

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法中缀表达式是我们平常最常见的表达式形式,但在计算机的运算过程中,我们常常需要将中缀表达式转换成后缀表达式,因为后缀表达式具有易于计算的特点。

那么,接下来我们将介绍三种将中缀表达式转换成后缀表达式的方法。

一、栈的方法这种方法是最常见的一种方法,也是比较易理解的一种方法。

我们可以借助栈来完成中缀表达式转换成后缀表达式的过程。

具体的操作如下:1. 声明一个操作符的栈stack(栈中存放操作符)和一个后缀表达式的列表res(列表中存放转换后的后缀表达式)。

2. 从左到右遍历中缀表达式。

3. 若当前字符为数字,则直接将该数字添加到res中。

4. 若当前字符为左括号“(”,则将其压入stack栈中。

5. 若当前字符为右括号“)”,则依次弹出stack栈中的操作符并加入到res中,直到遇到左括号为止。

6. 若当前字符为操作符,那么则需判断当前操作符与stack栈顶操作符的优先级,若当前操作符的优先级小于等于栈顶操作符,则弹出栈顶操作符并加入到res中,重复此步骤,直到当前操作符大于栈顶操作符优先级,最后将当前操作符压入stack栈。

7. 当遍历完整个中缀表达式后,若stack栈中还有剩余操作符,则依次弹出栈顶操作符并加入到res中。

8. 最终,res中的表达式就是转换后的后缀表达式。

二、递归调用方法这种方法是使用递归的方式来完成。

具体的操作如下:1. 若当前遍历的字符为数字,则直接输出该数字。

2. 若当前遍历的字符为左括号“(”,则递归读取该括号内的表达式。

3. 若当前遍历的字符为右括号“)”,则返回。

4. 若当前遍历的字符为操作符,“x”,“/”,“+”,“-”,则递归调用该表达式右边的操作符,比如“x”,“/”,然后再递归调用左边的操作符,比如“+”,“-”,然后输出左操作数和右操作数,最后输出当前操作符。

5. 最终,输出的表达式即为转换后的后缀表达式。

三、判断法这种方法也是比较常见的一种方法。

逆波兰表达式

逆波兰表达式

逆波兰表达式逆波兰表达式表达式⼀般由操作数(Operand)、运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间,这称为中缀表达式(Infix Expression),如A+B。

波兰数学家Jan Lukasiewicz提出了另⼀种数学表⽰法,它有两种表⽰形式:把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB;把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+;其中,逆波兰表达式在编译技术中有着普遍的应⽤。

算法:⼀、将中缀表达式转换成后缀表达式算法:1、从左⾄右扫描⼀中缀表达式。

2、若读取的是操作数,则判断该操作数的类型,并将该操作数存⼊操作数堆栈3、若读取的是运算符(1) 该运算符为左括号"(",则直接存⼊运算符堆栈。

(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为⽌。

(3) 该运算符为⾮括号运算符:(a) 若运算符堆栈栈顶的运算符为括号,则直接存⼊运算符堆栈。

(b) 若⽐运算符堆栈栈顶的运算符优先级⾼或相等,则直接存⼊运算符堆栈。

(c) 若⽐运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压⼊运算符堆栈。

4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。

⼆、逆波兰表达式求值算法:1、循环扫描语法单元的项⽬。

2、如果扫描的项⽬是操作数,则将其压⼊操作数堆栈,并扫描下⼀个项⽬。

3、如果扫描的项⽬是⼀个⼆元运算符,则对栈的顶上两个操作数执⾏该运算。

4、如果扫描的项⽬是⼀个⼀元运算符,则对栈的最顶上操作数执⾏该运算。

5、将运算结果重新压⼊堆栈。

信息学初赛复习资料-综合练习

信息学初赛复习资料-综合练习

信息学初赛复习资料(综合练习)初赛考的知识点就是计算机基本常识、基本操作和程序设计基础知识。

其中选择题考查的是知识,而问题解决类型的题目更加重视能力的考查。

一般说来,选择题只要多用心积累就可以了。

问题解决题目的模式比较固定,大家应当做做以前的题目。

写运行结果和程序填空也需要多做题目,并且培养良好的程序阅读和分析能力,就像语文的阅读理解一样。

近几年来,初赛的考查范围有了很大的变化,越来越紧跟潮流了。

这就需要大家有比较广泛的知识,包括计算机硬件、软件、网络、简单的数据结构(例如栈、队列、树和图等)和简单的算法(例如排序、查找和搜索等),程序设计语言以及一些基本的数学知识和技巧(例如排列组合)。

但最主要的,还是取决于你对程序设计语言的熟悉程度,再加上认真仔细的心态。

综合练习下面四个不同进制的数中,最小的一个是。

(A)(11011001)2 (B)(75)10(C)(37)8(D)(A7)16如果52-19=33是成立的,则52、19、33分别是。

(A)八进制、十进制、十六进制(B)十进制、十六进制、八进制(C)八进制、十六进制、十进制(D)十进制、八进制、十六进制把下列二进制数分别化成八进制数、十六进制数和十进制数。

(1)1110B (2)-101010B (3)10.0101B (4) 101101.11B把下列十进制数转换成二进制数(按0舍1入取6位二进制小数)。

(1) 75 (2)1024 (3)0.2 (4)18.692用8位二进制定点整数或定点小数写出下列真值的原码、补码形式,然后用2位十六进制数表示。

(1)11001B (2)-10010B (3)100000B (4)-100000B (5)0.1B(6)-0.1B (7) 0.100111B (8) –0.100111B (9)-15/128D已知x的补码,写出补码的十六进制表示,再求出x的原码。

(1)[x]补=01010011B (2)[x]补=10001001B(3)[x]补=11111111B (4)[x]补=11000000B已知[x]原=10011011是定点纯小数,写出x的浮点数规格化形式。

最全华为上机试题及部分答案

最全华为上机试题及部分答案

2011年华为软件校园招聘编程测验1、请上机编写程序,按题目要求提交文件。

[详见考试说明,点击进入考试说明]3、评卷通过在给定用例输入下,严格按照试题要求比较考生实现函数的输出与预设输出。

两者相同则得分,不同则不得分。

4、评卷人保证测试用例输入参数的合法性,考生不用考虑输入参数非法或异常的情况5、评卷人保证测试用例输入在被测函数正常合法情况下使用不会导致程序错误6、如果考生函数异常导致程序崩溃或死循环,则自动评卷可能会被人为终止,剩余用例不被执行,无法得分7、基于上述阅卷规则,请考生严格按照题目要求功能实现程序,尽量保证实现函数的稳健性,同时建议完成一道题并调试保证正确性后,再考虑并实现下一题目(17)1,判断电话号码是否合法://要注意情况包含,有可能会同时出现几种不好的情况,要按照顺序输出错误。

不能同时输出好几种错误,应该是这样包含:先判断长度是否符合,再判断是否以86打头,再判断有无其他字符int fun(char num[]){ char *p=num;int n=strlen(num);if(n==13){if(*p=='8'&&*(p+1)=='6')while(*p!='\0'){if(*p>='0'&&*p<='9')p++;elsereturn 2;if(*p=='\0')return 0;}else return 3;}elsereturn 1;}int main(){char num[]="87139a3887671";int k=fun(num);cout<<k<<endl;return 0;}(18) 数组比较(20分)•问题描述:比较两个数组,要求从数组最后一个元素开始逐个元素向前比较,如果2个数组长度不等,则只比较较短长度数组个数元素。

前序表达式中序表达式后序表达式

前序表达式中序表达式后序表达式

前序表达式中序表达式后序表达式前序表达式 , 中序表达式 , 后序表达式中序表达式中序表达式即我们⽇常使⽤的表达式,从左往右阅读,结构清晰,但是需要括号改变优先级,对计算机不友好eg:(1+4)*3+10/5,2*3/(2-1)+3*(4-1)前序表达式(波兰表⽰法Polish notation,或波兰记法)前序表达式的特点是操作符置于操作数前⾯,如果操作符的元数(+是⼆元操作符,故元数是2),则语法上不需要括号仍然能被⽆歧义的解释,不需要⼝号改变优先级。

eg:中序表达式: (1+4)*3+10/5前序表达式: + * + 1 4 3 / 10 5前序表达式的计算:eg:+ * + 1 4 3 / 10 5step1: 10 / 5 => 2new expression: + * + 1 4 3 2step2: 1 + 4 => 5new expression: + * 5 3 2step3: 5 * 3 => 15new expression: + 15 2step4: 15 + 2 => 17前序表达式的求值:⾸先要从右⾄左扫描表达式,从右边第⼀个字符开始判断,如果当前字符是数字则继续扫描,如果当前字符是运算符,将运算符右边最近的两个数字做运算,结果作为新的字符记录下来。

⼀直扫描到表达式的最左端时,最后运算的值也就是表达式的值。

后序表达式(逆波兰表⽰法(Reverse Polish notation,RPN,或逆波兰记法)后序表达式所有的操作符置于操作数后⾯,因此也被称为后缀表⽰法。

逆波兰表⽰法不需要括号标识操作符的优先级。

eg:中序表达式: (1+4)*3+10/5后序表达式: 1 4 + 3 * 10 5 / +后序表达式的计算:eg:1 4 + 3 * 10 5 / +step1: 1 + 4 => 5new expression: 5 3 * 10 5 / +step2: 5 * 3 => 15new expression: 15 10 5 / +step3: 10 / 5 => 2new expression: 15 2 +step4: 15 + 2 => 17后序表达式的求值:后序表达式的求值和前序表达式⼗分相似,后序表达式是从左⾄右扫描表达式,从左边第⼀个字符开始判断,如果的那个字符是数字继续扫描,如果是运算符,将运算符左边最近的两个数字做运算,结果作为新的字符记录下来。

习题课

习题课

第一章一、填空题:1.数据结构是一门研究非数值计算程序设计中计算机的操作对象以及它们之间的关系和运算的学科。

2.从逻辑上可以把数据结构分为线性结构和非线性结构。

3.线性结构的顺序存储结构是一种随机存取的存储结构,线性结构的链式存储是一种顺序存取的存储结构。

4.线性结构中元素的关系是一对一,树形结构中元素的关系是一对多,图形结构中元素的关系是多对多。

5算法的5个重要特征是有穷性、确定性、可行性、输入、输出。

6 算法分析的两个主要方面是:时间复杂度和空间复杂度二、判断题:1、顺序存储方式只能用于线性结构、不能用于非线性结构。

×2、基于某种逻辑结构之上的运算,其实现是唯一的。

×3、数据元素是数据的最小单位。

×4、数据结构是带有结构的数据元素的集合。

√5、算法分析的目的是研究算法中的输入和输出的关系×三、分析以下程序段的时间复杂度:5.(1)i=1;k=100while(i<n){K=k+1;i+=10;}(2)i=1;j=0;while(i+j<=n)if(i>j) j++;else i++;(3)x=n;y=0;while(x>=(y+1)*(y+1))y++;(4)x=91;y=100;while(y>0)if(x>100){x-=10;y--}else x++;(5)for(i=1;i<=n;i++)for(j=1;j<=i;j++)for(k=1;k<=j;k++)x=x+y;(1)O(n)(2)O(n)(3)O(n1/2)(4)O(1)(5)O(n3)第二章一、选择题:1.带头结点的单链表head为空的判断条件是(B)A.head=NULLB.head->next=NULLC.head->next=headD.head!=NULL2. 若在线性表中做以下两个操作:(1)在最后一个元素之后插入一个元素(2)删除第一个元素在(D)存储方式最节省时间:A. 单链表B. 单循环链表C. 双向链表D. 带尾指针的单循环链表3. 若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新元素算法的时间复杂度为(C)。

前序后序中序详细讲解

前序后序中序详细讲解

前序后序中序详细讲解1.引言1.1 概述在数据结构与算法中,前序、中序和后序是遍历二叉树的三种基本方式之一。

它们是一种递归和迭代算法,用于按照特定的顺序访问二叉树的所有节点。

通过遍历二叉树,我们可以获取有关树的结构和节点之间关系的重要信息。

前序遍历是指先访问根节点,然后递归地访问左子树,最后递归地访问右子树。

中序遍历是指先递归地访问左子树,然后访问根节点,最后递归地访问右子树。

后序遍历是指先递归地访问左子树,然后递归地访问右子树,最后访问根节点。

它们的不同之处在于访问根节点的时机不同。

前序遍历可以帮助我们构建二叉树的镜像,查找特定节点,或者获取树的深度等信息。

中序遍历可以帮助我们按照节点的大小顺序输出树的节点,或者查找二叉搜索树中的某个节点。

后序遍历常用于删除二叉树或者释放二叉树的内存空间。

在实际应用中,前序、中序和后序遍历算法有着广泛的应用。

它们可以用于解决树相关的问题,例如在Web开发中,树结构的遍历算法可以用于生成网页导航栏或者搜索树结构中的某个节点。

在图像处理中,前序遍历可以用于图像压缩或者图像识别。

另外,前序和后序遍历算法还可以用于表达式求值和编译原理中的语法分析等领域。

综上所述,前序、中序和后序遍历算法是遍历二叉树的重要方式,它们在解决各种与树有关的问题中扮演着关键的角色。

通过深入理解和应用这些遍历算法,我们可以更好地理解和利用二叉树的结构特性,并且能够解决更加复杂的问题。

1.2文章结构文章结构是指文章中各个部分的布局和组织方式。

一个良好的文章结构可以使读者更好地理解和理解文章的内容。

本文将详细讲解前序、中序和后序三个部分的内容和应用。

首先,本文将在引言部分概述整篇文章的内容,并介绍文章的结构和目的。

接下来,正文部分将分为三个小节,分别对前序、中序和后序进行详细讲解。

在前序讲解部分,我们将定义和解释前序的意义,并介绍前序在实际应用中的场景。

通过详细的解释和实例,读者将能更好地理解前序的概念和用途。

转:c#字符串公式计算

转:c#字符串公式计算

转:c#字符串公式计算C# ⾃动计算字符串公式的值(三种⽅式)从⽹络上找到这段源码,重新整理后测试通过.有三种⽅式可⾃动计算字符串公式的值:1. 最简单的⽅式,由SQL语句计算2. 使⽤Microsoft.Javascript计算3. 使⽤后序表达式计算(数据结构)原⽂内容:在编程应⽤程序过程中,有时需要字符串表达式的值。

如字符串:"23+56/(102-100)*((36-24)/(8-6))",计算结果=191。

根据数据结构栈的应⽤介绍,通过把表达式由中序式转换成后序式,再⽤栈来进⾏计算。

如上述字符串表达式:"23+56/(102-100)*((36-24)/(8-6))",转换为后序时为:"23|56|102|100|-|/|*|36|24|-|8|6|-|/|*|+"(其中字符"|"为分隔符)。

本程序代码如下:在VS2008 +winXP下编译通过。

C# Code:/// <summary>/// C#⾃动计算字符串公式的值/// </summary>public class CalcStringExpression{/// <summary>/// 最简单的⽅式由SQL计算/// </summary>/// <param name="expression">表达式</param>/// <returns></returns>public static float CalcBySQL(string expression){string SQL = "SELECT " expression " AS RESULT_VALUE";SqlConnection conn = new SqlConnection("⾃⼰定义连接字符串");SqlCommand cmd = new SqlCommand(SQL, conn);object o = cmd.ExecuteScalar(); //执⾏SQL.return float.Parse(o.ToString());}/// <summary>/// 由Microsoft.Eval对象计算表达式,需要引⽤Microsoft.JScript和Microsoft.Vsa名字空间。

(完整word版)大学数据结构期末知识点重点总结(考试专用)

(完整word版)大学数据结构期末知识点重点总结(考试专用)

第一章概论1。

数据结构描述的是按照一定逻辑关系组织起来的待处理数据元素的表示及相关操作,涉及数据的逻辑结构、存储结构和运算2。

数据的逻辑结构是从具体问题抽象出来的数学模型,反映了事物的组成结构及事物之间的逻辑关系可以用一组数据(结点集合K)以及这些数据之间的一组二元关系(关系集合R)来表示:(K, R)结点集K是由有限个结点组成的集合,每一个结点代表一个数据或一组有明确结构的数据关系集R是定义在集合K上的一组关系,其中每个关系r(r∈R)都是K×K上的二元关系3.数据类型a。

基本数据类型整数类型(integer)、实数类型(real)、布尔类型(boolean)、字符类型(char)、指针类型(pointer)b。

复合数据类型复合类型是由基本数据类型组合而成的数据类型;复合数据类型本身,又可参与定义结构更为复杂的结点类型4.数据结构的分类:线性结构(一对一)、树型结构(一对多)、图结构(多对多)5。

四种基本存储映射方法:顺序、链接、索引、散列6。

算法的特性:通用性、有效性、确定性、有穷性7.算法分析:目的是从解决同一个问题的不同算法中选择比较适合的一种,或者对原始算法进行改造、加工、使其优化8.渐进算法分析a.大Ο分析法:上限,表明最坏情况b.Ω分析法:下限,表明最好情况c.Θ分析法:当上限和下限相同时,表明平均情况第二章线性表1.线性结构的基本特征a.集合中必存在唯一的一个“第一元素”b。

集合中必存在唯一的一个“最后元素"c.除最后元素之外,均有唯一的后继d。

除第一元素之外,均有唯一的前驱2.线性结构的基本特点:均匀性、有序性3。

顺序表a.主要特性:元素的类型相同;元素顺序地存储在连续存储空间中,每一个元素唯一的索引值;使用常数作为向量长度b。

线性表中任意元素的存储位置:Loc(ki)= Loc(k0)+ i * L(设每个元素需占用L个存储单元)c. 线性表的优缺点:优点:逻辑结构与存储结构一致;属于随机存取方式,即查找每个元素所花时间基本一样缺点:空间难以扩充d.检索:ASL=【Ο(1)】e。

中序转后序表达式

中序转后序表达式

中序表达式是一种二叉树表达式,用来表示一棵二叉树的节点值的中序遍历顺序。

中序表达式通常是一串用空格分隔的节点名,例如“左左右右右”。

而后序表达式是另一种二叉树表达式,它表示二叉树的节点值的后序遍历顺序。

后序表达式通常是一串用空格分隔的节点名,但是与中序表达式不同的是,后序表达式中最后一个出现的节点是根节点,例如“左右右”。

要将一个中序表达式转换为后序表达式,可以按照以下步骤进行:
1. 将中序表达式中的第一个节点记为根节点。

2. 从中序表达式中的第二个节点开始,依次根据中序表达式中该节点后面的所有节点的先后顺序,递归地将每个节点作为子表达式的根节点,并将该节点及其后代节点从中序表达式中删除。

3. 将剩余的节点组成新的后序表达式。

例如,对于中序表达式“左右左”,它对应的二叉树为:

/ \
左右
/ \ \
左右左
按照上述步骤,可以将其转换为后序表达式“左右右”。

需要注意的是,在中序表达式和后序表达式转换的过程中,可能会出现空节点或多个节点的情况,需要进行相应的处理。

波兰式转换为逆波兰式

波兰式转换为逆波兰式

波兰式转换为逆波兰式(中缀表达式转换为后缀表达式)逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)一、定义i=0; /*获取用户输入的表达式*/do{i++;cin>>str[i];/*此步我用的是C++ C语言的话在后面之所以用这个有一点区别都*/ //scanf("%c",&str[i]);}while(str[i]!='#' && i!=max);sum=i;t=1;i=1;ch=str[i];i++;//while(ch!='#'){switch(ch){case '(': /*判定为左括号*/top++;stack[top]=ch;break;case ')': /*判定为右括号*/while(stack[top]!='('){ex[t]=stack[top];top--;t++;}top--;break;case '+': /*判定为加减号*/case '-':while(top!=0&&stack[top]!='('){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case '*': /*判定为乘除号*/case '/':while(stack[top]=='*'||stack[top]=='/'){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case ' ':break;default:while(ch>='0'&&ch<='9'){ /*判定为数字*/ex[t]=ch;t++;ch=str[i];i++;}i--;ex[t]=' ';t++;}ch=str[i];i++;}while(top!=0){ex[t]=stack[top];t++;top--;}ex[t]=' ';printf("\n\t原来表达式:");for(j=1;j<sum;j++)printf("%c",str[j]);printf("\n\t逆波兰式:",ex);for(j=1;j<t;j++)printf("%c",ex[j]);}void compvalue(){ /*计算后缀表达式的值*/float stack[max],d; /*作为栈使用*/char ch;int t=1,top=0; /*t为ex下标,top为stack下标*/ch=ex[t];t++;while(ch!=' '){switch(ch){case '+':stack[top-1]=stack[top-1]+stack[top];top--;break;case '-':stack[top-1]=stack[top-1]-stack[top];top--;break;case '*':stack[top-1]=stack[top-1]*stack[top];top--;break;case '/':if(stack[top]!=0)stack[top-1]=stack[top-1]/stack[top];else{printf("\n\t除零错误!\n");exit(0); /*异常退出*/}top--;break;default:d=0;while(ch>='0'&&ch<='9'){d=10*d+ch-'0'; /*将数字字符转化为对应的数值*/ch=ex[t];t++;}top++;stack[top]=d;}ch=ex[t];t++;}printf("\n\t计算结果:%g\n",stack[top]);}void main(){trans();compvalue();}数据结构版int precede(char op){ int x;switch(op){case '*': x=2; break;case '/': x=2; break;case '+': x=1; break;case '-': x=1; break;default : x=0;}return x;}char *RPExpression(char *e){/* 返回表达式e的逆波兰式 */char *c;c=(char*)malloc(sizeof(char)*20); //不能用char c[] Stack s1;InitStack(s1);int i=0,j=0;char ch;Push(s1,'@');ch=e[i++];while(ch!= 0){if(ch=='('){Push(s1,ch);ch=e[i++];}else if(ch==')'){while(Top(s1)!='('){Pop(s1,c[j++]);}/* to[j++]=pop(&s1);*/Pop(s1,ch);ch=e[i++];}else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){char w;w=Top(s1);while(precede(w)>=precede(ch)){Pop(s1,c[j++]);w=Top(s1);}Push(s1,ch);ch=e[i++];}else{//while((ch<='z'&&ch>='a')||(ch<='Z' && ch>='A')){c[j++]=ch;ch=e[i++];//}//c[j++]=' ';}}Pop(s1,ch);while(ch!='@'){c[j++]=ch;Pop(s1,ch);}//c[j++]=;c[j++]=0;return c;}还有一种方法,用2叉树.二叉树法将最终进行的运算符记为根节点,将两边的表达式分别记为左右子树,依次进行直到所有的运算符与数字或字母标在一棵二叉树上。

C++中缀表达式计算

C++中缀表达式计算

C++中缀表达式计算功能:输⼊⼀个中缀表达式的值(+ - * / ( ) )然后得出计算结果设计:1 第⼀步将中缀表达式转换为后缀表达式,每⼀个表达式都对应⼀个符号表达式数,中缀表达式是对数做中序遍历,⽽后缀表达式则是对次数做后缀遍历,学过数据结构的应该对此很熟悉了,借助堆栈可以轻松实现此点,在此我要说明的⼀点是,由于⼀个整数可能会占⼀个字符,⽐如“456”就占了3位,所以为了标识每个数在转换为后缀表达式后在每个数后⾯都加上了⼀个“#”,譬如“16 +28”转换后即为“16#28#+”2第⼆步相对来说就简单很多了,利⽤堆栈对后序表达式进⾏计算就可以了下⾯给出源码⾸先是头⽂件,⾥⾯是⾃⼰⽤链表实现的⼀个堆栈,很简单,在此不多做解释1 #ifndef STACK_H2#define STACK_H34 template<typename T>5class Stack;67 template<typename T>8class SNode9 {10 friend class Stack<T>;11private:12 T m_Data;13 SNode *m_pNext;14 };1516 template<typename T>17class Stack18 {19public:20 Stack();21 ~Stack();22public:23void Push(T data);24 T Pop();25bool IsEmpty();26 T GetTop();27private:28 SNode<T> *m_pTop;29 };3031 template<typename T>32 Stack<T>::Stack()33 {34 m_pTop=new SNode<T>;35 m_pTop->m_pNext=NULL;36 }3738 template<typename T>39void Stack<T>::Push(T data)40 {41 SNode<T> *pNode=new SNode<T>;42 m_pTop->m_Data=data;43 pNode->m_pNext=m_pTop;44 m_pTop=pNode;45 }4647 template<typename T>48 T Stack<T>::Pop()49 {50 SNode<T> *pNode=m_pTop->m_pNext;51if(pNode==NULL)52 {53 std::cout<<"Stack is empty"<<std::endl;54 exit(0);55 }56 m_pTop->m_pNext=pNode->m_pNext;57 T data=pNode->m_Data;58 delete pNode;59 pNode=NULL;60return data;61 }6263 template<typename T>64bool Stack<T>::IsEmpty()65 {66return m_pTop->m_pNext==NULL;67 }6869 template<typename T>70 T Stack<T>::GetTop()71 {72 SNode<T> *pNode=m_pTop->m_pNext;73return pNode->m_Data;74 }75 template<typename T>76 Stack<T>::~Stack()77 {78 SNode<T> *pNode=m_pTop->m_pNext,*pCur;79while(pNode!=NULL)80 {81 pCur=pNode;82 pNode=pNode->m_pNext;83 delete pCur;84 }85 }然后是两个函数,第⼀个函数将中序表达式换为后序表达式,第⼆个对后序表达式进⾏计算这是第⼀个函数此函数基于如下算法顺序的读⼊中序表达式,若遇到字符为操作数时则直接输出,并接着读下⼀字符,若单词为运算符时,取栈顶变量与当前变量的优先级做⽐较,若栈顶元素的优先级较⾼或相等,则栈顶元素退栈并输出到后序表达式中,接着新的栈顶变量与之⽐较。

数据结构_期中试卷(含答案)

数据结构_期中试卷(含答案)

一、选择题(每小题 1分,共10分)1、队列是插入和删除受限的线性表,其删除操作是在线性表的(1)进行。

A.表头 B.表尾 C.任意位置 D.指定位置2、下述哪一条是顺序存储结构的优点(2)。

A.存储密度大 B.插入运算方便C.删除运算方便 D.可方便地用于各种逻辑结构的存储表示3、设有一个栈,元素的进栈次序为A, B, C, D, E,下列哪个是不可能的出栈序列(3)。

A.A, B, C, D, E B.B, C, D, E, AC.E, A, B, C, D D.E, D, C, B, A4、若二叉树的根结点所在的层次为第1层,则该二叉树的第k层上至多有(4)个结点。

2k B.2k C.2k-1 D.2k+1A. 15、设单链表中指针p指向结点m,若要删除m的后继结点(假设该后继结点存在),则需修改指针的操作为(5)。

A.p->next=p->next->next; B.p=p->next;C.p=p->next->next; D.p->next=p;6、下面程序段的时间复杂度为(6)。

for(int i=0; i<m; i++)for(int j=0; j<n; j++) a[i][j] = i*j;A.O(m2) B.O(n2) C.O(m+n) D. O(m*n)7、非空的循环单链表head的尾结点指针p满足(7)。

A.p==NULL B.p== head C.p->next==head D.p->next==NULL8、已知二维数组A[0..9,0..9]中,元素a[2][0]的地址为560,每个元素占4个字节,则元素a[1][0]的地址为(8)。

A. 518B. 520C. 522D. 5249、在具有n个单元的顺序存储的循环队列中,假定front和rear分别为队头指针和队尾指针,则判断队满的条件为(9)。

A.rear%n= = front B.(front+l)%n= = rearC.rear%n -1= = front D.(rear+l)%n= = front10、假设在一棵二叉树中,度为2的结点数为15,度为1的结点数为10个,则该二叉树的分支总数为(10)个。

数据结构先序中序后序理解

数据结构先序中序后序理解

数据结构先序中序后序理解一、先序遍历先序遍历是指首先访问根节点,然后按照先序遍历的方式遍历左子树,最后再遍历右子树。

具体来说,先序遍历的顺序是根节点→左子树→右子树。

先序遍历的特点是能够保证根节点最先被访问,适用于需要先处理根节点的场景。

先序遍历常用的应用场景包括二叉树的构建和重建、表达式的求值和转换、图的深度优先搜索等。

在二叉树的构建和重建中,先序遍历可以用来确定根节点的位置,进而构建整棵二叉树。

而在表达式的求值和转换中,先序遍历可以将中缀表达式转换为后缀表达式,方便进行求值。

在图的深度优先搜索中,先序遍历可以帮助我们找到从起始节点出发的所有路径。

二、中序遍历中序遍历是指先遍历左子树,然后访问根节点,最后再遍历右子树。

具体来说,中序遍历的顺序是左子树→根节点→右子树。

中序遍历的特点是能够保证节点按照从小到大的顺序被访问,适用于需要按照顺序处理节点的场景。

中序遍历常用的应用场景包括二叉搜索树的操作、中序表达式的求值和转换等。

在二叉搜索树的操作中,中序遍历可以按照从小到大的顺序输出树中的所有节点,方便进行查找和排序操作。

在中序表达式的求值和转换中,中序遍历可以将中缀表达式转换为前缀或后缀表达式,方便进行求值。

三、后序遍历后序遍历是指先遍历左子树,然后遍历右子树,最后访问根节点。

具体来说,后序遍历的顺序是左子树→右子树→根节点。

后序遍历的特点是能够保证根节点最后被访问,适用于需要先处理子节点的场景。

后序遍历常用的应用场景包括二叉树的销毁和释放、表达式树的构建等。

在二叉树的销毁和释放中,后序遍历可以先销毁子节点,最后释放根节点的内存,避免内存泄漏。

在表达式树的构建中,后序遍历可以根据后缀表达式构建整棵表达式树,方便进行表达式的求值。

先序遍历、中序遍历和后序遍历是数据结构中常用的三种遍历方式。

它们各自具有不同的特点和应用场景,能够帮助我们更好地处理和操作数据。

在实际应用中,我们需要根据具体的需求选择合适的遍历方式,以达到最优的效果。

计算机专业基础综合历年真题试卷汇编1

计算机专业基础综合历年真题试卷汇编1

计算机专业基础综合历年真题试卷汇编1(总分:62.00,做题时间:90分钟)一、单项选择题(总题数:27,分数:54.00)1.单项选择题1-40小题。

下列每题给出的四个选项中,只有一个选项是最符合题目要求的。

(分数:2.00)__________________________________________________________________________________________解析:2.先序序列为a,b,c,d的不同二叉树的个数是_______。

(分数:2.00)A.13B.14 √C.15D.16解析:解析:根据二叉树前序遍历和中序遍历的递归算法中递归工作栈的状态变化得出:前序序列和中序序列的关系相当于以前序序列为入栈次序,以中序序列为出栈次序。

因为前序序列和中序序列可以唯一地确定一棵二叉树,所以题意相当于“以序列a,b,c,d为入栈次序,则出栈序列的个数为?”,对于n个不同元素进栈,出栈序列的个数为 C 2n n =14。

3.假设栈初始为空,将中缀表达式a/b+(c*d-e*f)/g转换为等价的后缀表达式的过程中,当扫描到f时,栈中的元素依次是_______。

(分数:2.00)A.+(*-B.+(-* √C./+(*-*D./+-*解析:解析:将中缀表达式转换为后缀表达式的算法思想如下:从左向右开始扫描中缀表达式;遇到数字时,加入后缀表达式;遇到运算符时: a.若为‘(’,入栈; b.若为‘)’,则依次把栈中的的运算符加入后缀表达式中,直到出现‘(’,从栈中删除‘(’; c.若为除括号外的其他运算符,当其优先级高于除‘(’以外的栈顶运算符时,直接入栈。

否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。

当扫描的中缀表达式结束时,栈中的所有运算符依次出栈加入后缀表达式。

4.在一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是_______。

电大数据结构复习题(填空题)

电大数据结构复习题(填空题)

a,b,c,d,e一系列栈操作SSXSXSSXXX之后,得到的输出序列为 bceda 。 30、 一个递归算法必须包括 终止条件 和 递归部分 。 31、 判断一个循环队列LU(最多元素为m0)为空的条件是 LU>front==LU->rear 。 32、 在将中缀表达式转换成后缀表达式和计算后缀表达式的算法 中,都需要使用栈,对于前者,进入栈中的元素为表达式中的 运算符 ,而对于后者,进入栈的元素为 操作数 ,中缀表 达式(a+b)/c-(f-d/c)所对应的后缀表达式是 ab+c/fde/-- 。 33、 向一个栈顶指针为h的链栈中插入一个s所指结点时,可执行 s>next=h; 和h=s;操作。(结点的指针域为next)。 34、 从一个栈顶指针为h的链栈中删除一个结点时,用x保存被删结 点的值,可执行x=h->data;和 h=h->next; 。(结点的指针域 为next) 35、 在一个链队中,设f和r分别为队头和队尾指针,则插入s所指 结点的操作为 r->next=s; 和r=s; (结点的指针域为next) 36、 在一个链队中,设f和r分别为队头和队尾指针,则删除一个结 点的操作为 f=f->next; 。 (结点的指针域为next) 37、 串是一种特殊的线性表,其特殊性表现在组成串的数据元素都 是 字符 。 38、 串的两种最基本的存储方式是 顺序存储方式 和 链式存储 方式 。 39、 空串的长度是 0 ;空格串的长度是 空格字符的个数 。 40、 需要压缩存储的矩阵可分为 特殊 矩阵和 稀疏 矩阵两种。 41、 设广义表L=((),()),则表头是 () ,表尾是 ()) ,L的长度是 2 。 42、 广义表A((a,b,c),(d,e,f))的表尾为 ((d,e,f)) 。 43、 两个串相等的充分必要条件是 串长度相等且对应位置的字符 相等 。 44、 设有n阶对称矩阵A,用数组s进行压缩存储,当ij时,A的数组 元素aij相应于数组s的数组元素的下标为 i(i-1)/2+j 。(数组 元素的下标从1开始)。

关系表达式的计算

关系表达式的计算

关系表达式的计算近期在做⼀个项⽬,涉及到⼀些简单的规则匹配。

规则的判定条件可以⽤关系表达式描述,形如(P1|P2)&(P3|P4)。

其中&是与,|是或,P1-P4是Pattern,具体的匹配条件,返回值是True或者False。

为计算此表达式的值,采⽤中序转后序再计算表达式的值。

1. 后序表达式的⽣成中序表达式转后序表达式算法:1. ⽤&|()对原表达式进⾏拆分,得到List<String>。

2. 从前往后遍历该List:(1)如果是⼀个pattern,则⼊栈。

(2)如果是左括号(,也⼊栈。

(3)如果是右括号:(a)如果此时栈为空,则表⽰表达式解析异常,报警并退出。

(b)如果栈不为空,则依次pop栈顶元素,直到匹配到左括号(。

如果没有左括号(的匹配,则表达式依次,报警并退出。

(4)如果是&和|:(a)如果栈为空,直接⼊栈。

(b)如果栈不为空,依次出栈直到匹配左括号(左括号不出栈)。

再把操作符⼊栈。

3、所有的pattern和操作符都⼊栈以后,把栈中所有元素依次出栈,就得到后序表达式。

参考代码:List<String> postfix = new ArrayList<String>();Stack<String> stack = new Stack<String>();String delims = "&|()"; // ⽀持的操作符StringTokenizer st = new StringTokenizer(rule, delims, true);while (st.hasMoreTokens()) {String tk = st.nextToken();if (!delims.contains(tk)) {// pattern,直接⼊栈postfix.add(tk);} else if (tk.equals("(")) {// 左括号,⼊栈stack.push(tk);} else if (tk.equals(")")) {if (stack.empty()) {// 碰到右括号,如果栈为空,解析异常throw new RuleException("parseRule Error!");}String val = stack.pop();// 如果栈不为空,依次出栈直到匹配左括号while (!val.equals("(")) {postfix.add(val);if (!stack.empty()) {val = stack.pop();} elsebreak;}if (stack.empty() && !val.equals("(")) {// 如果匹配不到左括号,解析异常throw new RuleException("parseRule Error!");}} else if (tk.equals("&") || tk.equals("|")) {if (stack.empty()) {// 碰到操作符,如果栈空,则直接⼊栈stack.push(tk);} else {// 如果栈不为空,依次出栈直到匹配左括号while (!stack.empty() && !stElement().equals("(")) {postfix.add(stack.pop());}// 操作符⼊栈stack.push(tk);}}}// 所有的pattern和操作符匹配完毕,把堆栈中还有的数据依次出栈while (!stack.empty()) {postfix.add(stack.pop());}System.out.println("Original Rule:" + rule);System.out.println("Postfix Rule: " + postfix.toString());2. 后序表达式的计算后序表达式的计算算法:1. 从前往后遍历中序表达式:(1)如果是&|操作符,则pop两个字段r1和r2,计算r1&r2或r1|r2的值r3,并将r3⼊栈。

数据结构复习试题

数据结构复习试题

题目选至第7章一、填空题(2分/题,共10题)1.数据是指所有能够输入到计算机中被计算机加工、处理的符号的集合。

2.可以把计算机处理的数据,笼统地分成数值型和非数值型两大类。

3.数据的逻辑结构就是指数据间的邻接关系。

10.从整体上看,数据在存储器有两种存放的方式:一是集中存放在一个连续的存存储区中;一是利用存储器中的零星区域,分散地存放在存的各个地方。

12.“基本操作”是指算法中那种所需时间与操作数的具体取值无关的操作。

5.不带表头结点的链表,是指该链表的表头指针直接指向该链表的起始结点。

6.在一个双链表中,已经由指针ptr指向需要删除的存储结点,则删除该结点所要执行的两条操作是①ptr->Prior->Next = ptr->Next; ②ptr->Next->Prior = ptr->Prior; 。

7.设tail是指向非空、带表头结点的循环单链表的表尾指针。

那么,该链表起始结点的存储位置应该表示成 tail->Next->Next 。

9.顺序表Sq = (a1,a2,a3,…,an)(n≥1)中,每个数据元素需要占用w个存储单元。

若m为元素a1的起始地址,那么元素an的存储地址是 m+(n-1)*w 。

1.限定插入和删除操作只能在一端进行的线性表,被称为是栈。

2.如果在顺序栈满时仍打算进行进栈操作,就称为发生了“上溢”出错。

3.如果在顺序栈空时仍打算进行出栈操作,就称为发生了“下溢”出错。

4.在具有n个数据结点的循环队列中,队满时共有 n-1 个数据元素。

5.如果操作顺序是先让字母A、B、C进栈,做两次出栈;再让字母D、E、F进栈,做一次出栈;最后让字母G进栈,做三次出栈。

最终这个堆栈从栈顶到栈底的余留元素应该是 DA 。

6.中缀表达式(a+b)-(c/(d+e))对应的后缀表达式是 ab+cde+/- 。

7.函数的递归调用有两种形式:如果一个函数是直接调用自己,就称其为直接递归调用;如果一个函数是通过另一个函数来调用自己,就称其为间接递归调用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("%c pop from the stack\n",operand1);
postorder[j++]=operand1;
printf("print %c\n",operand1);
}
}
else
{
if(priority(string[i])<=priority(operand->num))
int is_operator(char ch);
int two_result(int oper,int operand1,int operand2 );
int priority(char ch);
int i=0;
int j=0;
//----------------------------------------------------------------------------------------
p->next=NULL;
if(p==NULL)
{
printf("memory allocation failure!!!\n");
exit(0);
}
/*if(p==NULL)
{
printf("memory allocation failure!!!\n");
printf("print %c\n",string[i]);
}
i++;
}
while(!empty(operand))
{
operand=pop(&operand1,operand);
printf("%c pop from the stack\n",operand1);
link operand=NULL; //操作数堆栈
//****************
//函数声明
//****************
link push(int data,link top);
link pop(int *value,link top);
int empty(link Operator);
postorder[j++]=operand1;
} printf("print %c\n",operand1);
postorder[j]='\0';
printf("the postorder expression is:");
for(k=0;k<MAX;k++)
{
//主程序
//----------------------------------------------------------------------------------------
int main()
{
char string[MAX];
char postorder[MAX];
default: return 0;
}
}
//----------------------------------------------------------------------------------------
//计算两个操作数的值
//----------------------------------------------------------------------------------------
int two_result(int oper,int operand1,int operand2 )
{
switch(oper)
{
case '+': return (operand2+operand1);
case '-': return (operand2-operand1);
{
operand=pop(&operand1,operand);
printf("%c pop from the stack\n",operand1);
postorder[j++]=operand1;
printf("print %c\n",operand1);
{
if(is_operator(string[i])) //判断是否位运算符
{
if(empty(operand)||string[i]=='(')
{
operand=push(string[i],operand);
int priority(char ch)
{
switch(ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
#include<stdio.h>
#include<stdlib.h>
#define MAX 20
struct list
{
int num;
struct list *next;
};
typedef struct list NODE;
typedef NODE *link;
//----------------------------------------------------------------------------------------
link pop(int *value,link top)
{
link p;
p=NULL;
if(top!=NULL)
//判断运算符堆栈是否为空
//----------------------------------------------------------------------------------------
int empty(link Operator)
{
if(Operator==NULL)
}
operand=push(string[i],operand);
printf("%c push the stack\n",string[i]);
}
}
}
else
{
postorder[j++]=string[i]; //if it's an operand then print it
}*/
p->num=data;
p->next=top;
top=p;
return top;
}
//----------------------------------------------------------------------------------------
//从堆栈中取出数据
int operand1=0;
int k;
//for(;i<MAX;i++)
//postorder[i]=32;
printf("please input inorder expression=>");
gets(string);
while(string[i]!='\0'&&string[i]!='\n')
case '*': return (operand2*operand1);
case '/': return (operand2/operand1);
}
return 0;
}
return 1;
else
return 0;
}
//----------------------------------------------------------------------------------------
//判断是否是运算符
//----------------------------------------------------------------------------------------
//=============================program description=======================================
//程序名称:1.c
//程序目的:将中序表达式转换成后序表达式
//written by Lin
//=======================================================================================
printf("%c push the stack\n",string[i]);
}
else
{
if(string[i]==')')
{
while(operand->num!='(')
{
operand=pop(&operand1,operand);
int is_operator(char ch)
{
相关文档
最新文档