3_特殊线性表
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
f(n)
3
* Add n
(f) Fact(0)返回
操作步骤:
//出栈 // S1:如果栈空,则下溢; // S2:暂存栈顶结点,取该结 点值; // S3:栈顶指针后移; // S4:删除原栈顶结点,返回 其值。
x an
p top an an-1
...
a1 ∧
22
顺序栈和链栈的比较
top
栈顶 top
an
an-1
栈顶
栈底
X B A
stacksize
an
p
an-1
a1 ∧
21
链栈出栈
算法描述:
template<class T> T LinkStack<T>::Pop() { if (top = = NULL) throw"下溢"; p = top; x = top->data; top = top->next; delete p; return x; }// LinkStack
an an-1
top
栈顶
栈底
a1
∧
栈底
栈底
a1
∧
a1
∧
a. 链栈结构示意
b. 入栈
c.出栈
17
链栈特点
栈顶
an an-1
栈底
a1 ∧
链式栈无栈满问题,空间可扩充
插入与删除仅在栈顶处执行
链式栈的栈顶在链头
适合于多栈操作
18
链栈的结点定义
链表的结点结构与单链表的结点相同
template<class T> data next struct Node { T data; Node<T> *next;//此处T可以省略 };
前缀表示法
OP + S1 + S2
+ 1 / * 2 – 7 4 3
后缀表示法
S1 + S2 + OP 1 2 7 4 – * 3 / +
27
中缀表达式后缀表达式
单击右键,选择“播放”
28
中缀表达式转换为后缀表达式
Step 1:创建一个操作符栈 Step 2:从左到右扫描读取表达式,执行下列运算, 直至表达式结束符 2.1 如果是操作数,输出; 2.2 如果是操作符θ 2,把操作符栈栈顶的算符θ 1与θ 2 进行比较 2.2.1 2.2.2 2.2.3 θ 1<θ 2 ,θ 2入操作符栈 θ 1 = = θ 2,从操作符栈退出一个操作 符,不输出 θ 1>θ 2 ,从操作符栈输出所有比θ 2优先 级高的算符,直至栈顶算符优先级小于 θ 2,θ 2入操作符栈
29
运算符优先级定义
θ2 θ1 + * / ( ) #
+
> > > > < > <
> > > > < > <
*
< < > > < > <
/
< < > > < > <
(
)
#
< > > < > > < > > < > > < = error error > > < error =
30
后缀式求值
先找运算符,再找操作数
//把十进制整数N转化为八 进制数输出 // S1:构造一个空栈 // S2:当N≠0,求八进制 数各数字位 2.1 N % 8 入栈 2.2 N←N / 8 // S3:如果栈不空, 输出 八进制数各数制位 3.1 出栈 3.2 输出
26
表达式的三种标识方法
中缀表示法
S1 + OP + S2
1 + 2 * (7 – 4 ) / 3
main() { ... y = Fact(3); *: ... }
Fact(0)
...
Fact(3)
...
Fact(2) return(y)
...
· · ·
33
递归程序执行
调用过程
# # # y * Add y n y 3 y3 y y # * Add n * Add n 2 3 y2 y3 y y # # * Add n 1 2 3 y1 y2 y3 y y
stacksize
B A
… …
};
11
顺序栈成员函数
SqStack (int m); //构建函数
~SqStack ( );
void Push (T x); T Pop ( ); T GetTop ( ); int StackEmpty ( ); void ClearStack ( ); void StackTop ( );
//S1:空栈,不能出
throw “栈空,不能出栈”;
}
x = base[top--]; //S2:栈顶元素出栈 //S3:栈顶指针减一 return x; //S4:返回出栈元素
15
取栈顶元素算法
算法描述:
template <class T> T SqStack<T>::GetTop() { if ( top = = -1 ) throw "栈空,栈顶无元素"; return base[top]; } // S2:返回栈顶元素
//S1:栈满,不能入栈
top
top base
//S3:元素入栈顶
X B A
stacksize
14
顺序栈出栈算法
算法描述: template <class T> T Sq_Stack<T>::Pop() { 操作步骤: // 出栈
top top base
算法3.3
X B A
stacksize
if ( top = = -1)
第三章
特殊线性表
1
本章目录
3.1 栈
3.2 队列
小结
2
3.1 栈
1 2
栈定义及逻辑特性 顺序栈定义及实现 链栈定义及实现
3
4
栈的应用举例
3
栈 ( Stack )的定义
定义:限制只能在表的一端进行插入 和删除的线性表。 •允许插入和删除的一端,称为栈顶 (top)。
top 出栈 进栈
•不允许插入和删除的另一端,称为 栈底(bottom)。 •把一个元素从栈顶放入栈中的操作, base 称为进栈、入栈或压栈 (push) •从栈顶取出一个元素的操作称为出 栈或弹出(pop)。
// S3:栈顶指针指向s
top
s
x
an
... a2
a1 ∧
Q:为什么没有判断栈满 ?
20
链栈出栈
链栈出栈即删除链表的首元素结点。 操作步骤: T LinkStack<T>::Pop() Step 1:如果栈空,则下溢; if(top = = NULL) throw"下溢"; top Step 2:暂存栈顶结点,取该结点值; top x = top->data; Step 3:栈顶指针后移; top = top->next; Step 4:删除原栈顶结点,返回其值。 delete p; return x; Q: top++可以吗?
abcde/f+
ab
d/e
c-d/e
(c-d/e)f
ab+(c-d/e)f
31
后缀表达式计算
Step 1:创建一个栈,作为操作数栈
Step 2:执行下列操作,直到表达式结束
2.1 读取表达式
2.2 如果是操作数,入操作数栈 2.3 如果是操作符t,从操作数栈退出两个操作 数b、a,进行运算a t b,并把运算结果入操作数 栈
f(n)
Add
n
(a) 初态
(b) main调用Fact(3)
(c) 调用Fact(2)
(d) 调用Fact(1)
(e) 调用Fact(0)
返回过程
# # * Add n 2 3 1 y3 y y # 2 y y * Add 6 n y Add n 6 y (i) Fact(3)返回到main()
34
算法3.4
取栈顶元素操作是取出栈顶元素,但不改变栈。 操作步骤:
//获取栈顶元素 // S1:栈空,栈顶没有元素
top
X B A
stacksize
base
16
栈的链式存储及实现
栈的链式存储结构称为链栈(linked stack)。
栈顶 top
top 栈顶
X
s
an an-1
top
× an an-1
top ×
13
顺序栈入栈算法
算法描述: template <class T> void SqStack<T>::Push (T x ) { 操作步骤: //入栈
算法3.2
if (top = = stacksize-1)
throw "栈满,无法入栈"; top++; // S2:栈顶指针增1 base[top]=x; }
Push(&S, e) Pop(&S, &e) GetTop(S) StackEmpty(S) ClearStack(&S)
测栈空
清空栈
8
栈的操作示例
操作
InitStack( )
Push(2) Push(1) Push(8)
输 出
栈内数据元素
2 2,1 2,1, 8 2,1 2,1 2,1
Pop( ) GetTop( ) StackEmpty( ) ClearStack Pop( ) StackEmpty( )
19
链栈入栈算法
操作步骤: 算法描述: template<class T> //入栈 void LinkStack<T>::Push(T x) // S1:创建一个值为入栈元素 { 的新结点s; s=new Node<T>; // S2:新结点s插入表头;
s->data=x; s->next=top; top=s; }
数据关系:
R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }
约定an 端为栈顶,a1 端为栈底。 基本操作: .....
} ADT Stack
7
栈的基本操作
操作名 InitStack(&S)
功能说明
初始化栈 销毁栈 入栈 出栈 获取栈顶元素
DestroyStack(&S)
8 1 0
异常 1
9
栈的顺序存储及实现
栈满
5
栈空
top top top top top top top F E D C B A 5
4 3
2 1 top base 0
top top top top top
top
F E
2 1 0
栈空
进栈
出栈 base[top]出 top--;
Step 3:栈顶元素即为表达式的值
32
例3:递归
long int Fact(int n) { if(n<0) exit(0);//参数非法 if(n= = 0) y = 1; // 递归的边界 else y = n * Fact(n-1);//递归调用 #: retrun y; }
main( ) Fact(3) Fact(2) Fact(1) return(y) Fact(1) Fact(0) return (y) return (y)
base
时间:出、入栈均是常数级。 空间:顺序栈容量受限
a1 ∧ 栈底
链
栈因指针需额外存储空间
元素个数多且变化较大时,适宜用链栈; 反之,宜采用顺序栈
23
栈的应用举例 1. 数制转换 2. 表达式求值
24
例1:数制转换
算法基于原理: N = (N div d)×d + N mod d
单击右键,选择“播放”
base:基址指针 top:栈顶指针, 初值为-1
top++; base[top]<--元素
栈空,出栈,则下溢(underflow) 栈满,入栈,则上溢(overflow)
10
顺序栈的定义与实现
定义: template <class T> class SqStack top { private: base T *base; //栈底指针 int top; //栈顶 int stacksize; //栈容量 public:
25
10_8 数制转换类算法
void conversion10_8(int N) { Stack<int> s ; while (N) { s.Push (N%8 ); N = N/8; } while (!s.StackEmpty()) {
e = s.Pop( );
cout<<e; }
} // conversion10_8
an . . . a1
4
入 栈
入栈
出栈
栈顶 栈顶 栈顶 栈底
a3 a2 a1
插入:入栈、进栈、压栈 删除:出栈、弹栈
5
出 栈
入栈
出栈
栈顶
栈顶
栈底
a3 a2 a1
插入:入栈、进栈、压栈
删除:出栈、弹栈
栈的操作特性:后进先出
6
栈的抽象数据类型定义
ADT Stack {
数据对象:
D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 }
//析构函数
//入栈 //出栈 //获取栈顶元素 //测栈空 //清空栈 //返回栈顶指针
void StackTranverse ( ); //显示栈中元素
12
创建顺序栈
算法3.1
操作步骤: 算法描述 template <class T> // 创建栈 SqStack<T>::SqStack(int m) { //S1:申请栈空间 base = new T[m]; if (base = = NULL) { exit(1); //申请失败,退出 } m stacksize = m; stacksize top=-1; //S2:申请成功, } 给栈属性赋初值 top base 初始化工作可在构造函数中实现。