栈 栈的应用 栈的应用 队列 队列 优先队列 优先队列 a1a1 a2a2 a3a3 a4a4 a5a5 a6a6 插入 x i 删除 x j 插入 删除 栈 ( Stack )

Slides:



Advertisements
Similar presentations
Senem Kumova Metin Spring2009 STACKS AND QUEUES Chapter 10 in A Book on C.
Advertisements

第六章 数组与字符串 §6.1 数组 §6.2 字符串. §6.1 数组 数组的创建 ( 一维数组和二维数组;基本数据类型和 复合数据类型) 1. 指定数组名称、数据类型 type var_name[]; 如: char s[]; Object o[]; int i[][];
The unorganized person’s data structure
第十二章 常微分方程 返回. 一、主要内容 基本概念 一阶方程 类 型 1. 直接积分法 2. 可分离变量 3. 齐次方程 4. 可化为齐次 方程 5. 全微分方程 6. 线性方程 类 型 1. 直接积分法 2. 可分离变量 3. 齐次方程 4. 可化为齐次 方程 5. 全微分方程 6. 线性方程.
队列. Queues 队列 队列 (Queues) 是生活中 “ 排队 ” 的抽象。队列 的特点是: – 一些元素的线形序列; – 新加入的元素排在队尾,出队的元素在对头 进行,即插入和删除只能在队的两段进行; – 先来的先得到服务;故称为先进先出表 (FIFO, first in first.
基本知识和几何要素的投影 模块一: 字体练习 第一章 制图的基本知识与基本技能 题目提示返回.
第 12 章位运算 C 语言兼具高级语言及低级语言的特性,因此 适合编写系统软件。 C 语言具备低级语言的特性 就在于它能直接对硬件进行操作,即位运算。 所谓位运算是指,按二进制位进行的运算。 例如,将一个存储单元中各二进位左移或右移一 位等。
细分曲面 傅孝明 SA 目录 细分曲面的基本思想 两个关键问题 一些基本概念 几种简单的细分曲面算法 细分曲面方法分类.
第二章 数据信息 自然语言 字 -  单词 -  句子-  语言 计算机语言 字符-  词法单位-  程序-  语言 ↑ 词法 文法.
离心泵性能测定实验 指导教师:. 一、实验目的 ⒈熟悉离心泵的操作方法。 ⒉掌握离心泵特性曲线的测定方法、表示 方法,加深对离心泵性能的了解。
主要内容  LR(0) 分析. 0 S→  E # E→  E+T E→  T T→  id T→  ( E ) 1 S→E  # E→E  +T 5 T→id  3 E→E+  T T→  id T→  (E) 4 E→E+T  9 E→T  6 T→(  E) E→
嵌入式操作系统 陈香兰 Fall 系统调用 10/27/09 嵌入式 OS 3/12 系统调用的意义  操作系统为用户态进程与硬件设备进行交互提供 了一组接口 —— 系统调用  把用户从底层的硬件编程中解放出来  极大的提高了系统的安全性  使用户程序具有可移植性.
2.2 结构的抗力 抗力及其不定因素 材料强度的标准值 材料强度的设计值.
1/29 程序设计基础 程序设计是计算机学科的核心和灵魂 第一章 程序设计与 C ++语言初步 2/29 介绍一些简单的概念 硬件: 计算机及其它直接参与数据运算或信息交流的 物理设备 软件: 控制计算机硬件功能及其运行的指令、例行程 序和符号语言 程序: 一组按照一定的逻辑的进行组合的指令.
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第六十二讲 ) 离散数学. 最后,我们构造能识别 A 的 Kleene 闭包 A* 的自动机 M A* =(S A* , I , f A* , s A* , F A* ) , 令 S A* 包括所有的 S A 的状态以及一个 附加的状态 s.
递 归 (recursion)  定义 : 若一个对象部分地包含它自己, 或用 它自己给自己定义, 则称这个对象是递归的; 若一个过程直接地或间接地调用自己, 则称这个过程是递归的过程。  三种递归情况   定义是递归的  数据结构是递归的  问题的解法是递归的.
1 为了更好的揭示随机现象的规律性并 利用数学工具描述其规律, 有必要引入随 机变量来描述随机试验的不同结果 例 电话总机某段时间内接到的电话次数, 可用一个变量 X 来描述 例 检测一件产品可能出现的两个结果, 也可以用一个变量来描述 第五章 随机变量及其分布函数.
有限自动机 (Finite Automata) 描述程序设计语言中的单词的识别过程。 主要内容: 确定有限自动机 DFA(Deterninistic FA) 确定有限自动机 DFA 的实现 非确定有限自动机 NFA(Nondeterninistic FA) NFA 到 DFA 的转换 DFA 的化简.
例9:例9: 第 n-1 行( -1 )倍加到第 n 行上,第( n-2 ) 行( -1 )倍加到第 n-1 行上,以此类推, 直到第 1 行( -1 )倍加到第 2 行上。
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第三十八讲 ) 离散数学. 第八章 格与布尔代数 §8.1 引 言 在第一章中我们介绍了关于集 合的理论。如果将 ρ ( S )看做 是集合 S 的所有子集组成的集合, 于是, ρ ( S )中两个集合的并 集 A ∪ B ,两个集合的交集.
南航计算机系 南航计算机系 数据结构. 第一章 绪论  什么是数据结构 什么是数据结构  基本概念和术语 基本概念和术语  抽象数据类型的表示和实现 抽象数据类型的表示和实现  算法和算法分析 算法和算法分析.
Fall 2007CS 2251 Stacks Chapter 5. Fall 2007CS 2252 Chapter Objectives To learn about the stack data type and how to use its four methods: push, pop,
非线性科学 中的若干逆问题 非线性科学 中的若干逆问题 一、引论 : 一个逆问题的典范 —— 陈难先院士工作简介 二、 非线性科学中的逆问题 1. 逆强对称, 逆对称和逆可积梯 队 2. 从李代数到李群的逆问题 3. 求群不变解的逆问题 4. 分离变量法的逆问题.
第十一章 曲线回归 第一节 曲线的类型与特点 第二节 曲线方程的配置 第三节 多项式回归.
实验一: 信号、 系统及系统响应 1 、实验目的 1 熟悉连续信号经理想采样前后的频谱变化关系, 加深对时 域采样定理的理解。 2 熟悉时域离散系统的时域特性。 3 利用卷积方法观察分析系统的时域特性。 4 掌握序列傅里叶变换的计算机实现方法, 利用序列的傅里 叶变换对连续信号、 离散信号及系统响应进行频域分析。
第三章 C 数据及其表达式 2 回顾  程序是为执行一项任务而编写的有序指令集  算法是解决问题的具体方法和步骤  流程图是算法的图形化表现形式  C 程序的编译和运行过程  编译器将源程序转换成机器能理解的程序  连接器用于连接相关的目标文件以生成可执行程序  进制间的转换  补码.
线性代数习题课 吉林大学 术洪亮 第一讲 行 列 式 前面我们已经学习了关 于行列式的概念和一些基本 理论,其主要内容可概括为:
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第二十五讲 ) 离散数学. 定理 群定义中的条件 ( 1 )和( 2 )可以减弱如下: ( 1 ) ’ G 中有一个元素左壹适合 1 · a=a; ( 2 ) ’ 对于任意 a ,有一个元素左逆 a -1 适 合 a -1 ·
第二章 随机变量及其分布 第一节 随机变量及其分布函数 一、随机变量 用数量来表示试验的基本事件 定义 1 设试验 的基本空间为 , ,如果对试验 的每一个基 本事件 ,规定一个实数记作 与之对应,这样就得到一个定义在基本空 间 上的一个单值实函数 ,称变量 为随机变量. 随机变量常用字母 、 、 等表示.或用.
第 4 章 过程与变量的作用范围. 4.1 Visual Basic 的代码模块 Visual Basic 的应用程序是由过程组成的, 过程代码存放在模块中。 Visual Basic 提供了 三类模块,它们是窗体模块、标准模块和类 模块。 窗体模块 窗体模块是大多数 Visual Basic.
数 学 系 University of Science and Technology of China DEPARTMENT OF MATHEMATICS 第 3 章 曲线拟合的最小二乘法 给出一组离散点,确定一个函数逼近原函数,插值是这样的一种手段。 在实际中,数据不可避免的会有误差,插值函数会将这些误差也包括在内。
自顶向下分析 —— 递归下降法 递归下降法 (Recursive-Descent Parsing) 对每个非终极符按其产生式结构产生相应语 法分析子程序. 终极符产生匹配命令 非终极符则产生调用命令 文法递归相应子程序也递归,所以称这种方 法为递归子程序方法或递归下降法。
实验三: 用双线性变换法设计 IIR 数字滤波器 一、实验目的 1 熟悉用双线性变换法设计 IIR 数字滤波器的原理与方法。 2 掌握数字滤波器的计算机仿真方法。 3 通过观察对实际心电图信号的滤波作用, 获得数字滤波的感性知 识。
OS 进程调度模拟演示 制作人: 钱晶 高上上. OS 进程调度模拟-实验原理 静态优先级原理 在这种方式下,系统一旦把处理机分配给就绪队 列中的优先权最高的进程后,该进程便一直执行下去, 直至完成。或因为发生某事件使该进程放弃处理机,系 统方可再将处理机分配给另一优先级最高的进程。这些 事件包括有优先级更高的进程进入,或是因为某些原因.
量子化学 第四章 角动量与自旋 (Angular momentum and spin) 4.1 动量算符 4.2 角动量阶梯算符方法
数 学 系 University of Science and Technology of China DEPARTMENT OF MATHEMATICS 第 5 章 解线性方程组的直接法 实际中,存在大量的解线性方程组的问题。很多数值方 法到最后也会涉及到线性方程组的求解问题:如样条插值的 M 和.
从 Postscript 格式文献中提取 数学公式的方法. 概述 从 Postscript 格式文献中提取识别数学公式, 是数学公式识别领域的一个研究方向。主要针对 以 Word 和 Latex 为生成源的 Postscript 文档, 提出 基于内容的数学公式提取方法。首先重载 Postscript.
在发明中学习 线性代数 概念的引入 李尚志 中国科学技术大学. 随风潜入夜 : 知识的引入 之一、线性方程组的解法 加减消去法  方程的线性组合  原方程组的解是新方程的解 是否有 “ 增根 ” ?  互为线性组合 : 等价变形  初等变换  高斯消去法.
白 雪 飞 中国科学技术大学电子科学与技术系 Dept. of Elec. Sci. & Tech., USTC Fall, 2007 第 8 章 结 构 体.
东南大学计算中心 网站应用与实践 主讲人 吴俊. 2 东南大学计算中心 网站制作流程  确定主题、风格  规划栏目、收集素材  版面设计、配色  编辑页面  测试发布 FrontPage 要完成的任务.
第 3 章 控制流分析 内容概述 – 定义一个函数式编程语言,变量可以指称函数 – 以 dynamic dispatch problem 为例(作为参数的 函数被调用时,究竟执行的是哪个函数) – 规范该控制流分析问题,定义什么是可接受的控 制流分析 – 定义可接受分析在语义模型上的可靠性 – 讨论分析算法.
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第五十三讲 ) 离散数学. 定义 设 G= ( V , T , S , P ) 是一个语法结构,由 G 产生的语言 (或者说 G 的语言)是由初始状态 S 演绎出来的所有终止符的集合, 记为 L ( G ) ={w  T *
实验三: 用双线性变换法设计 IIR 数字滤波器 一、实验目的 1 熟悉用双线性变换法设计 IIR 数字滤波器的原理与方法。 2 掌握数字滤波器的计算机仿真方法。 3 通过观察对实际心电图信号的滤波作用, 获得数字滤波的感性知 识。
编译原理总结. 基本概念  编译器 、解释器  编译过程 、各过程的功能  编译器在程序执行过程中的作用  编译器的实现途径.
 符号表  标识符的作用: 声明部分:定义了各种对象及对应的属性和 使用规则。 程序体:对所定义的对象进行各种操作。 $ididname IdnameAttributeIR  必要性 Token : 新表-符号表(种类、类型等信息):
Lesson 4 Data Structure: Stacks, Queues and Linked Lists.
Data Structures: CSCI 362 – Stack Implementation Data Structures: CSCI 362 – Stack Implementation lecture notes adapted from Data Structures with C++ using.
Chapter Two– Data Numbering & Character Encoding System in Microcomputer Principles of Microcomputers 2015年10月22日 2015年10月22日 2015年10月22日 2015年10月22日 2015年10月22日.
Chapter 8 Algorithms. Understand the concept of an algorithm. Define and use the three constructs for developing algorithms: sequence, decision, and repetition.
1 、如果 x + 5 > 4 ,那么两边都 可得 x >- 1 2 、在- 3y >- 4 的两边都乘以 7 可得 3 、在不等式 — x≤5 的两边都乘以- 1 可得 4 、将- 7x — 6 < 8 移项可得 。 5 、将 5 + a >- 2 a 移项可得 。 6 、将- 8x < 0.
CHAPTER 2 INTRODUCTION TO STACKS 【 Problem 】 Read an integer n,which will be at most 25,then read a list of n numbers,and print the list in reverse order.
项目七: PLC 功能指令应用 带进位循环左移指令 XXXXX. 项目七: PLC 功能指令应用 FX2 系列可编程控制器移位控制指令有移位、循环移位、字移位 及先进先出 FIFO 指令等 10 条指令。 带进位循环右移指令 RCR 带进位循环左移指令 RCL 字右移位指令 WSFR 先入先出读出指令.
§10.2 对偶空间 一、对偶空间与对偶基 二、对偶空间的有关结果 三、例题讲析.
表单自定义 “ 表单自定义 ” 功能是用于制作表单的 工具,用数飞 OA 提供的表单自定义 功能能够快速制作出内容丰富、格 式规范、美观的表单。
个体 精子 卵细胞 父亲 受精卵 母亲 人类生活史 问题:人类产生配子(精、卵 细胞)是不是有丝分裂?
#include //ECH0.CPP main(int argc,char *argv[]) { for(int i=0;i
逻辑设计基础 1 第 7 章 多级与(或)非门电路 逻辑设计基础 多级门电路.
小组成员:冯小懋 刘得民 周彬彬 张振 Excel 在投资理财中的应用(第二节) 第二组. 名称框的应用 应用了名称框定义后,会在引用时直接引用定义的名称。 操作:选定要定义名称的位置,选择 “ 插入 ”——“ 名称 ”——“ 指定 ” 本题中选择 “ 最左列 ” ,也可以自己定义,若是定义同一个名称可.
面向对象程序设计 Guangzhou University 1 An object-based program is more interesting when multiple objects are involved. In addition to acting as peers or agents,
一、 版 面 构 成 的 概 念 版 面 构 成 的 概 念 二、 版 面 构 成 的 发 展 趋 势 版 面 构 成 的 发 展 趋 势 三、 广 告 文 字 的 版 面 构 成 广 告 文 字 的 版 面 构 成 四、 广 告 版 面 的 视 觉 流 程 广 告 版 面 的 视 觉 流 程.
Fall 2006 METU EEEEE 441 S. Ece (GURAN) SCH MIDT EE 441 Data Structures Lecture 6 Stacks and Queues.
Data Structures: A Pseudocode Approach with C1 Chapter 3 Objectives Upon completion you will be able to Explain the design, use, and operation of a stack.
1 第三章 数列 数列的概念 考点 搜索 ●数列的概念 ●数列通项公式的求解方法 ●用函数的观点理解数列 高考 猜想 以递推数列、新情境下的 数列为载体, 重点考查数列的通 项及性质, 是近年来高考的热点, 也是考题难点之所在.
Chapter 3 Stack and Queue 3.3 The Stack ADT Stack Model A stack is a list in which insertions and deletions take place at the same end. This end.
Main Index Contents 11 Main Index Contents Stacks Further Stack Examples Further Stack Examples Pushing/Popping a Stack Pushing/Popping a Stack Class StackClass.
第二章 线性表 第二节 线性链表 5. 线性表的链式表示 顺序表的优点是可以随机选取表中元素 缺点是插入删除操作复杂。 用指针将互不相连的内存结点串成的 线性表叫线性链表。 结点 node 由一个数据元素域,一个或几个 指针域组成。单链表的结点只有一个指针域。
目录 上页 下页 返回 结束 二、无界函数反常积分的审敛法 * 第五节 反常积分 无穷限的反常积分 无界函数的反常积分 一、无穷限反常积分的审敛法 反常积分的审敛法  函数 第五章 第五章.
Session 03 - Templates Outline 03.1Introduction 03.2Function Templates 03.3Overloading Template Functions 03.4Class Templates 03.5Class Templates and Non-type.
Lecture 6: Functions of Combinational Logic
Stack and Queues Stack implementation using Array
Presentation transcript:

栈 栈的应用 栈的应用 队列 队列 优先队列 优先队列

a1a1 a2a2 a3a3 a4a4 a5a5 a6a6 插入 x i 删除 x j 插入 删除 栈 ( Stack )

栈和队列 都是特殊的线性表 限定性的线性表 操作受限的线性表

一、栈  限定只在表的一端访问的线性表  元素只能从栈顶插入和删除  先进后出 后进先出 例 羊肉串 子弹夹 货 栈

top top A B C D top A B C D 顺序栈的模型 top B A C D top C B A D D C B A C B A D top B A C D top A B C D top A B C D

top top A B C D top A B C D top B A C D top B A C D top A B C D top A B C D top A B D C top D A B C top C D A B

顺序栈 —— 栈类的顺序表示 #ifndef STACK_CLASS #define STACK_CLASS #include const int MaxStackSize = 50;

template class Stack { T stacklist[MaxStackSize]; int top; public: Stack (void); void Push (const T& item); T Pop (void); void ClearStack(void); T Peek (void) const; //gettop int StackEmpty(void) const; int StackFull(void) const; };

// initialize stack top. template Stack ::Stack (void) : top(-1) { }

// push item on the the stack template void Stack ::Push (const T& item) { // if stacklist is full, terminate the program if (top == MaxStackSize-1) { cerr << "Stack overflow!" << endl; exit(1); } // increment top and copy item to stacklist top++; stacklist[top] = item; }

// pop the stack and return the top element template T Stack ::Pop (void) { T temp; // if stack is empty, terminate the program if (top == -1) { cerr << "Attempt to pop an empty stack!" << endl; exit(1); } temp = stacklist[top]; // record the top element top--; return temp; }

// return the value at the top of the stack template T Stack ::Peek (void) const { // if the stack is empty, terminate the program if (top == -1) { cerr << "Attempt to peek at an empty stack!" << endl; exit(1); } return stacklist[top]; }

// test for an empty stack template int Stack ::StackEmpty(void) const { // return the logical value top == - 1 return top == -1; }

// test for a full stack template int Stack ::StackFull(void) const { // test the position of top return top == MaxStackSize-1; }

// clear all items from the stack template void Stack ::ClearStack(void) { top = -1; } #endif // STACK_CLASS

链栈 栈的链式表示

线性链表类的定义

#include "node.h" template class LinkedList { Node *front, *rear, *prevPtr, *currPtr; int size; int position; Node *GetNode(const T& item,Node *ptrNext=NULL); void FreeNode(Node *p); void CopyList(const LinkedList & L); public: LinkedList(void); LinkedList(const LinkedList & L); ~LinkedList(void); LinkedList & operator= (const LinkedList & L); int ListSize(void) const;

int ListEmpty(void) const; void Reset(int pos = 0); void Next(void); int EndOfList(void) const; int CurrentPosition(void) const; void InsertFront(const T& item); void InsertRear(const T& item); void InsertAt(const T& item); void InsertAfter(const T& item); T DeleteFront(void); void DeleteAt(void); T& Data(void); void ClearList(void); };

链栈类的定义 #ifndef STACK_CLASS #define STACK_CLASS #include #include "link.h"

template class Stack { LinkedList stackList; public: Stack(void); // constructor void Push(const T& item); T Pop(void); T Peek(void); int StackEmpty(void) const; void ClearStack(void); };

// constructor template Stack ::Stack(void) { }

// uses the LinkedList method // ClearList to clear the stack template void Stack ::ClearStack(void) { stackList.ClearList( ); }

// use the LinkedList method //InsertFront to push item template void Stack ::Push(const T& item) { stackList.InsertFront(item); }

// use the LinkedList method DeleteFront to pop stack template T Stack ::Pop(void) { // check for an empty linked list if (stackList.ListEmpty( )) { cerr << "Popping an empty stack" << endl; exit(1); } // delete first node and return its data value return stackList.DeleteFront( ); }

// returns the data value of the first first item on the stack template T Stack ::Peek(void) {// check for an empty linked list if (stackList.ListEmpty( )) { cerr << "Calling Peek for an empty stack" << endl; exit(1); } // reset to the front of linked list and return value stackList.Reset( ); return stackList.Data( ); }

// use the LinkedList method //ListEmpty to test for empty stack template int Stack ::StackEmpty(void) const { return stackList.ListEmpty( ); } #endif // STACK_CLASS

二、 栈的应用  回文验证  数制转换  表达式求值  括号匹配检验  行编辑程序  递归实现

回文验证 palindrome 回文的例子 dad madam sees madam im adam a man a plan a canal panama

#include #pragma hdrstop #include "astack.h" // creates a new string with all blank characters removed void Deblank(char *s, char *t) { // loop through expression until NULL character is found while(*s != NULL) {// if character is a non-blank, copy to new string if (*s != ' ') *t++ = *s; s++; // move to next character } *t = NULL; // append NULL to new string }

void main(void) { const int True = 1, False = 0; Stack S; // stack elements are characters char palstring[80], deblankstring[80], c; int i = 0 ; int ispalindrome = True; // assume string is a palindrome cin.getline(palstring,80,'\n'); // read in the full-line string // remove blanks from string and put result in deblankstring Deblank(palstring,deblankstring); // push the chars of deblanked expression on the stack

i = 0; while(deblankstring[i] != 0) { S.Push(deblankstring[i]); i++; } i = 0; while (!S.StackEmpty( )) { c = S.Pop( ); // get next character from stack if (c != deblankstring[i]) { ispalindrome = False; break; } i++; }

if (ispalindrome) cout << '\"' << palstring << '\"' << " is a palindrome" << endl; else cout << '\"' << palstring << '\"' << " is not a palindrome" << endl; }

/* madam im adam "madam im adam" is a palindrome a man a plan a canal panama "a man a plan a canal panama" is a palindrome palindrome "palindrome" is not a palindrome */

数制转换 输入十进制数, 以其他进制输出 #include #pragma hdrstop #include "astack.h" // print integer num in base B

void MultibaseOutput(long num, int B) { // stack holds base B digits left to right Stack S; // extract base B digits right to left and push on stack S do { S.Push(int(num % B)); // convert to int and push on stack num /= B; // remove right most digit } while (num != 0); // continue until all digits computed while (!S.StackEmpty( )) // flush the stack cout << S.Pop( ); }

void main(void) { long num; // decimal number int B; // base // read 3 positive numbers and the desired base 2 <= B <= 9 for(int i=0;i < 3;i++) { cout << "Enter non-negative decimal number and base " << "(2<=B<=9): "; cin >> num >> B; cout << num << " base " << B << " is "; MultibaseOutput(num, B); cout << endl; }

/* Enter non-negative decimal number and base (2<=B<=9): base 4 is 1020 Enter non-negative decimal number and base (2<=B<=9): base 2 is Enter non-negative decimal number and base (2<=B<=9): base 8 is 6741 */

表达式求值 中缀表达式 a+b*c a+b*(c-d)+e/f (b*b-4*a*c)/(2*a) 后缀表达式 abc*+ abcd-*+ef/+ bb*4a*c*-2a*/

// 后缀表达式求值 //calc.h #include #pragma hdrstop enum Boolean {False, True}; #include "astack.h"

class Calculator {Stack S; // holds operands void Enter(double num); Boolean GetTwoOperands(double& opnd1, double& opnd2); void Compute(char op); public: Calculator(void); // evaluate an expression and clear calculator void Run(void); void Clear(void); };

// store data value on the stack void Calculator::Enter(double num) { S.Push(num); }

Boolean Calculator::GetTwoOperands( double& opnd1, double& opnd2) { if (S.StackEmpty( )) // check for presence of operand { cerr << "Missing operand!" << endl; return False; } opnd1 = S.Pop( ); // fetch right-hand operand if (S.StackEmpty()) { cerr << "Missing operand!" << endl; return False; } opnd2 = S.Pop( ); // fetch left-hand operand return True; }

void Calculator::Compute(char op) { Boolean result; double operand1, operand2; result = GetTwoOperands(operand1, operand2); if (result == True) switch(op) { case '+': S.Push(operand2+operand1); break; case '-': S.Push(operand2-operand1); break; case '*': S.Push(operand2*operand1); break; case '/': if (operand1 == 0.0) { cerr << "Divide by 0!" << endl; S.ClearStack( ); } else S.Push(operand2/operand1); break; case '^': S.Push(pow(operand2,operand1)); break; } else S.ClearStack( ); // error! clear calculator }

Calculator::Calculator(void) {}

void Calculator::Run(void) { char c; double newoperand; while(cin >> c, c != '=') // read until '=' (Quit) { switch(c) {case '+': case '-': case '*': case '/': case '^': Compute(c); break; default: // not operator, must be operand; put char back cin.putback(c); // read the operand and store it on the stack cin >> newoperand; Enter(newoperand);break; } } if (!S.StackEmpty( )) cout << S.Peek( ) << endl; }

void Calculator::Clear(void) { S.ClearStack( ); }

#include "calc.h" void main(void) { Calculator CALC; CALC.Run( ); }

/* 8 8 * 6 6 * +.5 ^ = * Missing operand! * = / = Divide by 0! */

中缀表达式求值 定义表达式等级 为表达式中每个元素赋一个等级 表达式的累计等级必须为 0 或 1 整个表达式的等级为 1 项等级 数 1 正负 运算 + - * / 左右括号( ) 0

5+3*-6 读到负号时等级累计 -1 ,出错 5+3- 最后等级 0 ,出错

中缀表达式求值法 用两个栈:一个存放操作数 一个存放运算符 2+3-4*5= 3 2+ 操作数 读入 “-” 弹出两个 - 优先级与 + 相同 操作数运算得到结 运算符 弹出 + 果 6 入栈 6- 操作数运算符 “-” 入栈 5 4* 6- 操作数 4 入栈 5 入栈 “*” 优先级高于 “-” 运算符 “*” 入栈 操作数 弹出 “*” 20 入栈 弹出 5 4 运算 运算符 操作数 弹出 “-” -14 入栈 弹出 20 6 运算 运算符 -14 操作数弹出结果 -14 运算符

定义运算符优先级 icp 栈外优先级 in coming priority isp 栈内优先级 in stack priority 运算符 icpisp 等级 * /22 ( 3 0 ) 000

#ifndef INFIX_MATH_OPERATIONS #define INFIX_MATH_OPERATIONS // list of constants specifying specific error messages const int OperatorExpected = 0, OperandExpected = 1, MissingLeftParenthesis = 2, MissingRightParenthesis = 3, InvalidInput = 4; // labels designating the parentheses characters const char leftparenthesis = '(', rightparenthesis = ')';

// a class that handles operators on the operator stack class MathOperator { char op; int icp , isp; public: MathOperator(void); MathOperator(char ch); int operator>= (MathOperator a) const; void Evaluate (Stack &OperandStack); char GetOp(void); };

// default constructor MathOperator::MathOperator(void) {}

MathOperator::MathOperator(char ch) { op = ch; // assign operator switch(op) { case ‘+’: case ‘-’: icp = 1; isp = 1; break; case ‘*’: case ‘/’: icp = 2; isp = 2; break; case ‘(’: icp = 3; isp = -1; break; case ')': icp = 0; isp = 0; break; }

int MathOperator::operator>= (MathOperator a) const { return isp >= a.icp; }

void MathOperator::Evaluate ( Stack &OperandStack) { float operand1 = OperandStack.Pop( ); float operand2 = OperandStack.Pop( ); switch (op) // select operation { case '+' : OperandStack.Push(operand2 + operand1); break; case '-': OperandStack.Push(operand2 - operand1); break; case '*': OperandStack.Push(operand2 * operand1); break; case '/': OperandStack.Push(operand2 / operand1); break; } }

// return operator associated //with current object char MathOperator::GetOp(void) { return op; } #endif // INFIX_MATH_OPERATIONS

#include #include // used for function 'isdigit' #pragma hdrstop #include "stack.h" // include template-based stack class #include "mathop.h" // defines the MathOperator class // checks if character is an operator or parentheses

int isoperator(char ch) { if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(') return 1; else return 0; }

// checks if character is a // whitespace character int iswhitespace(char ch) { if (ch == ' ' || ch == '\t' || ch == '\n') return 1; else return 0; }

// error handling function void error(int n) { // table gives the different error messages static char *errormsgs[] = { "Operator expected", "Operand expected", "Missing left parenthesis", "Missing right parenthesis", "Invalid input"}; cerr << errormsgs[n] << endl; exit(1); }

void main(void) { Stack OperatorStack; Stack OperandStack; MathOperator opr1,opr2; int rank = 0; float number; char ch; // process the expression until '=' is read while (cin.get(ch) && ch != '=') { // ******** process a floating point operand ******* * if (isdigit(ch) || ch == '.') { cin.putback(ch); cin >> number; rank++; if (rank > 1) error(OperatorExpected); OperandStack.Push(number); }

// ********* process an operator ********** else if (isoperator(ch)) { if (ch != '(') rank--; if (rank < 0) error(OperandExpected); opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty() && (opr2 = OperatorStack.Peek( )) >= opr1) { opr2 = OperatorStack.Pop(); opr2.Evaluate(OperandStack); } OperatorStack.Push(opr1); }

// ********* process an operator ********** else if (isoperator(ch)) { if (ch != '(') // rank of '(' is 0 rank--; if (rank < 0) error(OperandExpected); // build a MathOperator object holding current // operator. pop the operator stack and evaluate // as long as the operator on the top of the stack // has a precedence >= that of the current operator. // push the current operator on the operator stack opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty() && (opr2 = OperatorStack.Peek()) >= opr1) { opr2 = OperatorStack.Pop(); opr2.Evaluate(OperandStack); } OperatorStack.Push(opr1); } // ********* process a right parenthesis ********** else if (ch == rightparenthesis) { opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty( )&& (opr2 = OperatorStack.Peek( )) >=opr1) { opr2 = OperatorStack.Pop( ); opr2.Evaluate(OperandStack); } if(OperatorStack.StackEmpty( )) error(MissingLeftParenthesis); opr2 = OperatorStack.Pop( ); // get rid of '(' }

else if (!iswhitespace(ch)) error(InvalidInput);} if (rank != 1) error(OperandExpected); while (!OperatorStack.StackEmpty( )) { opr1 = OperatorStack.Pop( ); if (opr1.GetOp( ) == leftparenthesis) error(MissingRightParenthesis); opr1.Evaluate(OperandStack); } cout << "The value is " << OperandStack.Pop() << endl; }

/* /3 * = The value is 7.5 ( ) * 4 = The value is 21 (4 + 3) - 7) = Missing left parenthesis */

三、队列 允许一端插入另一端取出的线性表 先进先出 队尾 插入端 队头 取出端 ←a1a1 a2a2 a3a3 a4a4 a5a5 ← ←a2a2 a3a3 a4a4 a5a5 a6a6 ←

循环队列 a1a1 a2a2 a3a3 a4a4 a5a5 a3a3 a4a4 a5a5 a6a6 a7a7 a 8 a3a3 a4a4 a5a5 a6a6 a7a7 front rear a 0 front rear a 0 a 1 front rear a 0 a 1 a 2 a3 a3 front rear a 1 a 2 a3 a3 frontrear a3 a3 a4a4 a5a5 frontrear a3 a3 a4a4 a5a5 a6a6 frontrear a3 a3 a4a4 a5a5 a6a6 a 7 rear front a 8 a3 a3 a4a4 a5a5 a6a6 a 7 rearfront a 8 a 9 a3 a3 a4a4 a5a5 a6a6 a 7 rearfront

循环队列 --- 队列的顺序表示 #ifndef QUEUE_CLASS #define QUEUE_CLASS #include // maximum size of a queue list const int MaxQSize = 50;

template class Queue { int front, rear, count; T qlist[MaxQSize]; public: Queue (void); void QInsert(const T& item); T QDelete(void); void ClearQueue(void); T QFront(void) const; int QLength(void) const; int QEmpty(void) const; int QFull(void) const; };

// initialize queue front, rear, count template Queue ::Queue (void) : front(0), rear(0), count(0) {}

// insert item into the queue template void Queue ::QInsert (const T& item) { if (count == MaxQSize) { cerr << "Queue overflow!" << endl; exit(1); } count++; qlist[rear] = item; rear = (rear+1) % MaxQSize; }

// delete element from front of queue and return its value template T Queue ::QDelete(void) { T temp; if (count == 0) {cerr << "Deleting from an empty queue!" << endl; exit(1); } temp = qlist[front]; count--; front = (front+1) % MaxQSize; return temp; }

// return value of the first entry template T Queue ::QFront(void) const { return qlist[front]; }

// return number of queue elements template int Queue ::QLength(void) const { return count; }

// test for an empty queue template int Queue ::QEmpty(void) const { // return the logical value count == 0 return count == 0; }

// test for a full queue template int Queue::QFull(void) const { // return the logical value count == MaxQSize return count == MaxQSize; }

// clear the queue by resetting count, //front and rear to 0 void Queue::ClearQueue(void) { count = 0; front = 0; rear = 0; } #endif // QUEUE_CLASS

队列 Queue 类的链式定义 #ifndef QUEUE_CLASS #define QUEUE_CLASS #include #include "link.h"

template class Queue { LinkedList queueList; public: Queue(void); void QInsert(const T& elt); T QDelete(void); T QFront(void); int QLength(void) const; int QEmpty(void) const; void QClear(void); };

// constructor template Queue ::Queue(void) {}

// LinkedList method ListSize //returns length of list template int Queue ::QLength(void) const { return queueList.ListSize( ); }

// LinkedList method ListEmpty //tests for empty queue template int Queue ::QEmpty(void) const { return queueList.ListEmpty(); }

// LinkedList method ClearList //clears the queue template void Queue ::QClear(void) { queueList.ClearList( ); }

// LinkedList method InsertRear //inserts item at rear template void Queue ::QInsert(const T& elt) { queueList.InsertRear(elt); }

// LinkedList method DeleteFront // removes item from front template T Queue ::QDelete(void) { // test for an empty queue and terminate if true if (queueList.ListEmpty( )) { cerr << "Calling QDelete for an empty queue!" << endl; exit(1); } return queueList.DeleteFront( ); }

// return the data value from the first item in the queue template T Queue ::QFront(void) { if (queueList.ListEmpty()) { cerr << "Calling QFront for an empty queue!" << endl; exit(1); } // reset to front of the queue and return data queueList.Reset( ); return queueList.Data( ); } #endif // QUEUE_CLASS

队列的应用 windows 命令序列 打印命令序列 涉及排队的问题 基数排序

四、优先级队列 优先级最高的元素先出 Priority Queue

优先级队列 //apqueue.h #ifndef PRIORITYQUEUE_CLASS #define PRIORITYQUEUE_CLASS #include // maximum size of the priority queue array const int MaxPQSize = 50;

template class PQueue { int count; T pqlist[MaxPQSize]; public: PQueue (void); void PQInsert(const T& item); T PQDelete(void); void ClearPQ(void); int PQEmpty(void) const; int PQFull(void) const; int PQLength(void) const; };

// initialize priority queue count template PQueue ::PQueue (void) : count(0) {}

// insert item into the priority queue template void PQueue ::PQInsert (const T& item) { if (count == MaxPQSize) { cerr << "Priority queue overflow!" << endl; exit(1); } // place item at the rear of the list and increment count pqlist[count] = item; count++; }

template T PQueue ::PQDelete(void) { T min; int i, minindex = 0; if (count > 0) { min = pqlist[0]; for (i = 1; i < count; i++) if (pqlist[i] < min) { min = pqlist[i]; minindex = i; } pqlist[minindex] = pqlist[count-1]; count--; } else { cerr << "Deleting from an empty priority queue!" << endl; exit(1); } return min; }

// return number of list elements template int PQueue ::PQLength(void) const { return count; }

// test for an empty priority queue template int PQueue ::PQEmpty(void) const { return count == 0; }

// test for a full priority queue template int PQueue ::PQFull(void) const { return count == MaxPQSize; }

// clear the priority queue by resetting count to 0 template void PQueue ::ClearPQ(void) { count = 0; } #endif // PRIORITYQUEUE_CLASS