c++_栈和队列
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
子 过 程 3
r
r
s r
4.2 队列
4.2.1 队列的定义
定义:队列是限定只能在表的一端进行插 入,在表的另一端进行删除的线性表 队尾(rear)——允许插入的一端 队头(front)——允许删除的一端 队列特点:先进先出(FIFO) 例如:排队购物。操作系统中的作业排队。 先进入队列的成员总是先离开队列。
基本操作: } ADT Stack
基本操作
初始化:InitStack 销毁: DestroyStack
求长度:StackLength
判断栈空:StackEmpty 清空栈:ClearStack 压栈: Push 出栈: Pop
栈遍历:StackTravers
4.1.2 顺序栈及其运算
栈满 5 4 3 top top top top top top 栈空 top top top top top F E D C B A 出栈 5 4 3 2 1 0
表达式处理(后缀表达式)
后缀表达式求值步骤: 1、读入表达式一个字符 2、若是操作数,压入栈,转4 3、若是运算符,从栈中弹出2个数,将运算结果再压入栈 4、若表达式输入完毕,栈顶即表达式值; 若表达式未输入完,转1 例 计算 4+3*5 后缀表达式:435*+
top
4
top
3 4
top
5 3 4
队列定义
当队列中没有元素时称为空队列。在空队列中 依次加入元素a1,a2,…an之后,a1是队头元素,an是 队尾元素。
出队
a1 a2 front
a3…………………….an rear
入队
队列Q=(a1,a2,……,an)
ADT Queue
ADT Queue { 数据对象: D={ai | ai∈ElemSet, i=1,2,...,n, n≥0} 数据关系: R1={ <a i-1,ai > | ai-1, ai ∈D, i=2,...,n} 约定其中a1 端为队列头, an 端为队列尾 基本操作:
表达式处理(中缀表达式)
中缀表达式:运算符在操作数的中间 处理方法:操作数栈和运算符栈
例 计算 2+4-3*6
4 + 2 操作数 运算符 18 6 操作数 运算符 6 3 * 6 操作数 运算符
6 操作数 运算符
-12 操作数 运算符
表达式处理(中缀表达式)
中缀表达式是一种通用的算术或逻辑公式表示 方法,操作符以中缀形式处于操作数的中间。 中缀表达式是人们常用的算术表示方法。 虽然人的大脑很容易理解与分析中缀表达式, 但对计算机来说中缀表达式却是很复杂的,且 中缀表达式有不唯一的问题。因此计算表达式 的值时,通常需要先将中缀表达式转换为前缀 或后缀表达式,然后再进行求值。 对计算机来说,计算前缀或后缀表达式的值非 常简单。
数制转换(算法)
void conversion( ) { Stack <int> s; cin >> n; while(n) { s.push(n%8); n=n/8; } while(! s.Stackempty()) { e = s.pop(); cout << e; }
表达式处理(三种表达方法)
栈的运算------入栈
template <typename T> void linkstack<T>::push(T x) { stacknode<T> *p; p = new stacknode<T>(); p–>data = x; p–>next = top->next; top->next = p; }
进栈
出栈
...
栈顶
an ……... a2
栈s=(a1,a2,……,an)
栈底
a1
假设栈S=(a1,a2,a3,…an),则a1称为栈底元素,an为 栈顶元素。栈中元素按a1,a2,a3,…an的次序进栈,退栈 的第一个元素应为栈顶元素。
ADT Stack
ADT Stack { 数据对象: D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } 数据关系: R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n } 约定an 端为栈顶,a1 端为栈底。
①若读出运算符的优先级大于运算符栈栈顶运算符的优先级,
则将读出的运算符压入运算符栈,并依次读下一个符号。 ②若读出的是表达式结束符“;”,则表达式处理结束, 最后的计算结果在操作数栈的栈顶位置。 ③若读出运算符的优先级不大于运算符栈栈顶运算符的优先级, 则从操作数栈连续退出两个操作数,并从运算符栈退出一个 运算符,然后作相应的运算(运算符为刚从运算符栈退出的 运算符,运算对象为刚从操作数栈退出的两个操作数),并 将运算结果压入操作数栈。
top
15 4
top
19
top
括号匹配检验
假设在表达式中 ([]())或[([ ][ ] )]等为正确的格式, [( ])或([( ))或 (( )])均为不正确的 格式。
则 检验括号是否匹配的方法可用“期待的急迫 程度”这个概念来描述。即后出现的"左括弧",它 等待与其匹配的"右括弧"出现的"急迫"心情要比先 出现的左括弧高。
F E
D
5
4 3
2 1 0
2 1 top= -1 0
栈空
C B A 进栈
top top
栈顶指针top,初值为-1
设数组维数为M top=-1,栈空,此时出栈,则下溢(underflow) top=M-1,栈满,此时入栈,则上溢(overflow)
顺序栈的类型定义
顺序栈的类型定义:
连续存储的顺序表 存储空间 空间大小
数制转换
十进制N和其它进制数的转换算法基于下列原理: N=(n div d)*d+n mod d ( 其中:div为整除运算,mod为求余运算)
例 把十进制数159转换成八进制数
8
159
余7 余3 余2 2 3 7 top 7 3 top 7
8 19 8 2 0
top
2 3 7
top
(159)10=(237)8
栈顶:top
template <typename T> class Stack { T *data; int top; int maxSize; public: Stack(int size=100); ~Stack(); void initstack(); int stackempty(); int stackfull(); T pop(); void push(T x); …… };
它是运算是受限的单链表 插入和删除操作仅限制在表头位置上进行 栈顶指针就是链表的头指针
链栈的定义
template <typename T> class linkstack; template <typename T> class stacknode { friend class linkstack<T>; private: T data; stacknode<T> *next; }; template <typename T> class linkstack { private: stacknode<T> *top; public: //操作 ……. void initstack(); void push(T x) T pop(); T gettop(); };
} ADT Queue
队列基本操作
InitQueue
QueueEmpty EnQueue QueueTravers
DestroyQueue
QueueLength DeQueue ClearQueue
//栈空间起始地址 //栈顶 //栈最大容量
template <typename T>Stack<T>::Stack(int size) { maxSize = size; top =-1; data = new T[maxSize]; assert(data); }
栈的运算------初始化
template <typename T> void Stack<T>::initstack() { top = -1; }
栈的运算------取栈顶元素
template <typename T> T linkstack<T>:: gettop() { assert(!stackempty(stack)); return top–>next->data; }
4.1.4 栈的应用
数制转换 表达式处理 括号匹配检验 函数调用 递归问题
栈的运算------取栈顶元素
template <typename T> T Stack<T>:: gettop() { assert(!stackempty()); return data[top]; }
4.1.3 栈的链表表示
栈顶指针
an
an-1
a1 ∧
栈底元素
注意: 链栈中 指针的方向
链栈的类型说明
设 Exp = S1 OP S2
则称 OP S1 S2 为前缀表示法 S1 OP S2 为中缀表示法 S1 S2 OP 为后缀表示法 例如: Exp = a b + (c d / e) f 前缀式: +abc/def 中缀式: ab+cd/ef
后缀式:
abcde/f+
表达式处理(中缀表达式)
栈的运算------出栈
template <typename T> T linkstack<T>::pop() { T x; stacknode<T> *q = top->next; assert(!stackempty()) ; x = q–>data; top->next = q–>next; delete q; return x; }
括号匹配检验:算法设计思想
1)凡出现左括弧,则进栈; 2)凡出现右括弧,首先检查栈是否空 若栈空,则表明该“右括弧”多余 否则和栈顶元素比较, 若相匹配,则“左括弧出栈” 否则表明不匹配 3)表达式检验结束时, 若栈空,则表明表达式中匹配正确 否则表明“左括弧”有余
函数调用
主 程 序 r s 子 过 程 1 s r t 子 过 程 2 t s r
栈的运算---判断栈空
template <typename T> int Stack<T>::stackempty() { return (top == -1); }
栈的运算---判断栈满
template <typename T> int Stack<T>::stackfull() { return (top == StackSize-1); }
栈的运算------初始化
template <typename T> void linkstack<T>::initstack() { //带头结点的链式栈 top = new stacknode <T>(); top->next = NULL; }
栈的运算------判断栈空
template <typename T> int linkstack<T>::stackempty() { return top->next == NULL; }
第四章 栈和队列
4.1 栈
4.1.1 栈的定义 4.1.2 顺序栈及其运算 4.1.3 栈的链表表示 4.1.4 栈的应用
4.2 队列
4.2.1 4.2.2 4.2.3 4.2.4 队列的定义 顺序队列及其运算 队列的链表表示 队列的应用
总目录
4.1 栈
4.1.1 栈的定义
定义:限定仅在表尾进行插入或删除操作 的线性表,表尾—栈顶,表头—栈底,不含 元素的空表称空栈 特点:后进先出(LIFO)
运算符栈,用于在表达式处理过程中存放运 算符。 在开始时,运算符栈中先压入一个表达式结束 符“;”。 操作数栈,用于在表达式处理过程中存放操 作数。
表达式处理(中缀表达式)
从左到右依次读出表达式中的各个符号: 若是操作数,则压入操作数栈,依次读下一个符号。 若是运算符,则作进一步判断:
栈的运算-wk.baidu.com----入栈
template <typename T> void Stack<T>::push(T x) { assert (!stackfull()) data[++top] = x; }
栈的运算------出栈
template <typename T> T Stack<T>::pop() { assert(!stackempty()) x=data[top]; top--; return x; }