出栈序列相对入栈序列关系
数据结构-栈与队列
栈 1.6栈的应用
运算符的优先级关系表在运算过程中非常重要,它是判定进栈、出栈的重要依据。
θ1
θ2
+
-
+
>
>
-
>
>
*
>
>
/
>
>
(
<
<
)
>
>
#
<
<
*
/
(
)
#
<
<
<
>
>
<
<
<
>
>
>
>
<
>
>
>
>
<
>
>
<
<
<
=
>
>
>
>
<
<
<
=
栈
1.6栈的应用
下面以分析表达式 4+2*3-12/(7-5)为例来说明求解过程,从而总结出表达式求值的算 法。求解中设置两个栈:操作数栈和运算符栈。从左至右扫描表达式:# 4+2*3-12/(7-5) #, 最左边是开始符,最右边是结束符。表达式求值的过程如下表所示:
1.4栈的顺序存储结构
设计进栈算法——Push 函数。首先,判断栈是否已满,如果栈已满,就运用 realloc 函 数重新开辟更大的栈空间。如果 realloc 函数返回值为空,提示溢出,则更新栈的地址以及栈 的当前空间大小。最终,新元素入栈,栈顶标识 top 加 1。
数据结构测试试卷及答案
得分一、单项选择题(10 小题,每小题 2 分,共 20 分)1.设栈 S 和队列 Q 的初始状态为空,元素 e1,e2,e3,e4,e5,e6 依次通过栈 S,一个元素出栈后即进入队列 Q,若 6 个元素出队的顺序是 e2,e4,e3,e6,e5,e1,则栈 S 的容量至少应该是()。
BA.2B.3C.4D.62.由 4 个叶子结点构造一棵哈夫曼树,该树的总结点数是(A.4 B.5 C.6D)。
D.73.对于长度为m(m>1)的指定序列,通过初始为空的一个栈、一个队列后,错误的叙述是)。
(DA.若入栈和入队列的序列相同,则出栈序列和出队序列可能相同B.若入栈和入队列的序列相同,则出栈序列和出队序列可以互为逆序C.入队序列与出队序列关系为1:1,而入栈序列与出栈序列关系是1: n (n≥1)D.入队序列与出队序列关系为1: n (n≥1),而入栈序列与出栈序列关系是1:14.在一个单链表 HL 中,若要删除由指针 q 所指结点的后继结点,则执行(A)。
A.p=q->next; q->next=p->next; C.p=q->next; p->next=q->next;B.p=q->next; q->next=p;D.q->next= q->next->next; q->next=q;5.假设有如下遗产继承规则:丈夫和妻子可以相互继承遗产;子女可以继承父亲或母亲的遗产;子女之间不能相互继承。
则表示该遗产继承关系的数据结构应该是()。
A.树B.图C.线性表D.集合B6.设数组 S[n]作为两个栈 S1 和 S2 的存储空间,对任何一个栈只有当 S[n]全满时才不能进行进栈操作。
为这两个栈分配空间的最佳方案是(A.S1 的栈底位置为 0,S2 的栈底位置为n-1B.S1 的栈底位置为 0,S2 的栈底位置为n/2C.S1 的栈底位置为 0,S2 的栈底位置为nD.S1 的栈底位置为 0,S2 的栈底位置为 1A)。
栈和队列
应用3 :表达式求值
设计思路:用栈暂存运算符
应用4:汉诺仪(Hanoi)塔
设计思路:用栈实现递归调用
例 表达式求值
1)问题的提出 假若我们想在计算机上设计一个小计算器(程序), 其功能为:从键盘上输入一个算术表达式(由运算符操 作数构成的字符串),在屏目上显示输出表达式的求值结 果。 显然这个小计算器程序应该对你键入的表达式进行求 值。在该程序中如何对键入的表达式求值呢?又如,高 级语言中都有表达式,例赋值语句:变量=表达式;该 语句的执行过程为:先求出表达式的值, 然后将其值赋 给赋值号左边的变量。这个表达式的值是如何求出的?
我们看到:进行运算的算符i是当前扫描过的运算 符中优先级最高者,同时,也是到当前最后被保存的运 算符,由此可见,可以利用两个栈分别保存扫描过程中 遇到的操作数和运算符。
6 算法思想:
设定两栈:操作符栈 OPTR ,操作数栈 OPND 栈初始化:设操作数栈 OPND 为空;操作符栈 OPTR 的栈底 元素为表达式起始符 ‘#’; 依次读入字符:是操作数则入OPND栈,是操作符则要判断: if 操作符 < 栈顶元素,则退栈、计算,结果压入OPND栈; 操作符 = 栈顶元素且不为‘#’,脱括号(弹出左括号); 操作符 > 栈顶元素,压入OPTR栈。
问:堆栈是什么?它与一般线性表有什么不同?
答:堆栈是一种特殊的线性表,它只能在表的一端 (即栈顶)进行插入和删除运算。 与一般线性表的区别:仅在于运算规则不同。
一般线性表 逻辑结构:一对一 存储结构:顺序表、链表 运算规则:随机存取 堆栈 逻辑结构:一对一 存储结构:顺序栈、链栈 运算规则:后进先出(LIFO)
数据结构课程的内容
受限的线 性表
进出栈序列问题详解
进出栈序列问题详解链接:题⽬描述⼀列⽕车n 节车厢,依次编号为1,2,3,…,n 。
每节车厢有两种运动⽅式,进栈与出栈,问n 节车厢出栈的可能排列⽅式有多少种。
输⼊描述:⼀个数,n(n≤60000)n (n \leq 60000)n(n≤60000)输出描述:⼀个数s 表⽰n 节车厢出栈的可能排列⽅式⽰例1输⼊3输出5⽰例2输⼊50输出1978261657756160653623774456思路:⽅案⼀:暴⼒枚举对于栈问题,简单来想只有进栈和出栈的操作所以直观的来看,直接暴⼒枚举每个节点情况1.把下⼀个数进栈2.把当前栈顶元素出栈(如果栈⾮空)利⽤递归快速实现,时间复杂度 :O (2N )在这个时间复杂度下很容易TLE⽅案⼆:递推优化 O (N 2)因为本题只是要求求出有多少种出栈序列并不关⼼具体⽅案,于是我们可以使⽤递推直接进⾏统计。
设S N 表⽰进栈顺序为 1,2,3,4...,N 时可能的出栈序列总数。
现在假设序列中位置 K 的地⽅有⼀个数 a ,a 前⾯有K −1个数要出栈,a 后⾯有N −K 个数要出栈,⽽出栈的⽅案总数分别是 S K −1和 S N −K 于是这个⼤问题就转化成了⼩问题,我们就要求更⼩的 S i,于是有递推公式(很好理解):⽅案三:动态规划 O (N 2)动态规划。
这⾥我们要有状态与决策的思想(这个真的很重要,有时与搜索也异曲同⼯)。
我们设 F [i ,j ] 是还有 $i个元素未⼊栈,j$ 个元素在栈中的⽅案总数,初始状态是F [0,0]=1,⽬标状态是F [N ,0]F ,每⼀次我们的决策有“让⼀个数进栈”,“让栈顶的数出栈”,所以⽅程有:F [i ,j ]=F [i −1,j +1]+F [i ,j −1]{Processing math: 100%⽅案四:数学O(N)、该问题等价于求第N项Ctalan数,即C N2N/(N+1)。
大学数据结构课件--第3章 栈和队列
栈满 top-base=stacksize
top
F
E
D C B
top top top top top top base
入栈PUSH(s,x):s[top++]=x; top 出栈 POP(s,x):x=s[--top]; top
base
4
A
3.1 栈
例1:一个栈的输入序列为1,2,3,若在入栈的过程中 允许出栈,则可能得到的出栈序列是什么? 答: 可以通过穷举所有可能性来求解:
3.2 栈的应用举例
二、表达式求值
“算符优先法”
一个表达式由操作数、运算符和界限符组成。 # 例如:3*(7-2*3) (1)要正确求值,首先了解算术四则运算的规则 a.从左算到右 b.先乘除后加减 c.先括号内,后括号外 所以,3*(7-2*3)=3*(7-6)=3*1=3
9
3.2 栈的应用举例
InitStack(S); while (!QueueEmpty(Q))
{DeQueue(Q,d);push(S,d);}
while (!StackEmpty(S)) {pop(S,d);EnQueue(Q,d);} }
第3章 栈和队列
教学要求:
1、掌握栈和队列的定义、特性,并能正确应用它们解决实 际问题;
用一组地址连续的存储单元依次存放从队头到队尾的元素, 设指针front和rear分别指示队头元素和队尾元素的位置。
Q.rear 5 4 Q.rear 3 2 3 2 5 4 Q.rear 3 3 5 4 5 4
F E D C
C B A
Q.front
2 1 0
C B
Q.front 2 1 0
入栈和出栈规律
⼊栈和出栈规律
1.由来
jvm中堆主要是⽤来存对象的,⽐如Object obj= new Object(),obj就是存在jvm的堆中的,栈则是⽤来存成员属性的,每⼀个线程都有⼀个独⽴的栈,前⾯的obj同样也会在栈中保存⼀个,但是保存的不是对象,⽽是obj在堆中的内存地址。
当堆中的对象没有栈中的指针指向它时,就会被GC垃圾回收装置回收,栈的存取速度⼤于堆,⼩于寄存器,但是必须指定⼤⼩和⽣命周期。
2.⼊栈出栈规则
先进后出,不⼀定要全部⼊栈之后再出栈,没⼊栈完也可以先出栈
3.任何出栈元素后⾯的元素必须满⾜两条规则
1.在原序列(也就是⼊栈序列)中顺序⽐出栈元素⼩的,必须是逆序
2.在原序列(也就是⼊栈序列)中顺序⽐出栈元素⼤的,顺序⽆所谓
3.出栈元素表⽰的是出栈后⾯的所有元素
⽐如⼊栈的是12345,有下⾯两种情况:
a. 1 5 4 3 2 这个先看第⼀个元素1,1后⾯的元素每⼀个都⽐这个⼤,所以⽆所谓什么顺序,再看第⼆个元素5,5后⾯的元素都⽐这个数⼩,所以都必须遵循逆序,⽽432遵循逆序,所以没问题,情况成⽴。
b. 4 3 5 1 2 这个先看第⼀个元素4,4后⾯⽐它⼩的是312,⽽这个12明显不按逆序,也就是倒序排列,所以是有问题的。
以后碰到这个出栈顺序的⾯试题时,就可以分分钟选对了。
数据结构(C++版)第3章 特殊线性表
特殊线性表——栈
3.1.3 栈的链接存储结构及实现
链栈:栈的链接存储结构 first
a1
a2
ai
an ∧
将哪一端作为栈顶? 将链头作为栈顶,方便操作。 链栈需要加头结点吗? 链栈不需要附设头结点。
特殊线性表——栈
栈的链接存储结构及实现
链栈:栈的链接存储结构 first top an
栈顶
a1
a2 a1 ∧
Pop( );
an
an-1
a1 ∧
特殊线性表——栈
顺序栈和链栈的比较
时间性能:相同,都是常数时间O(1)。
空间性能: 顺序栈:有元素个数的限制和空间浪费的问题。 链栈:没有栈满的问题,只有当内存没有可用空间时才会 出现栈满,但是每个元素都需要一个指针域,从而产生了 结构性开销。 结论:当栈的使用过程中元素个数变化较大时,用链栈是适 宜的,反之,应该采用顺序栈。
两栈共享空间
两栈共享空间
0 1 2 ……
S-1
a 1 a2 … ai
栈1底
bj … … b2 b 1
top2
栈2底
top1
栈1的底固定在下标为0的一端; 栈2的底固定在下标为StackSize-1的一端。 top1和top2分别为栈1和栈2的栈顶指针; Stack_Size为整个数组空间的大小(图中用S表示);
an
an-1
p
a1 ∧ top++可以吗?
特殊线性表——栈
链栈的实现——链栈的析构(链栈的销毁)
template <class T> LinkStack<T>::~LinkStack( ) {
Node<T> *p;
ACCESS公共基础-栈和列队
特殊线性表特殊线性表特殊线性表例:有三个元素按栈的逻辑结构例:有三个元素按栈的逻辑结构例:有三个元素按栈的逻辑结构例:有三个元素按栈的逻辑结构栈的顺序存储结构及实现0 1 2 3 4 5 6 7栈的顺序存储结构及实现链栈:栈的链式存储结构及实现操作接口:链栈的实现操作接口:链栈的实现顺序栈和链栈的比较特殊线性表素出队时,头指针加1。
故在非空队列中,头指针始终指向队头元素前例:队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)例:队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)队列的顺序存储结构及实现(顺序队列)继续入队会出现什么情况?队列的顺序存储结构及实现(顺序队列)如何解决假溢出?队列的顺序存储结构及实现(顺序队列)如何实现循环队列?队列的顺序存储结构及实现(顺序队列)如何判断循环队列队空?队空的临界状态队列的顺序存储结构及实现(顺序队列)如何判断循环队列队空?执行出队操作队列的顺序存储结构及实现(顺序队列)如何判断循环队列队空?执行出队操作队列的顺序存储结构及实现(顺序队列)如何判断循环队列队满?队满的临界状态队列的顺序存储结构及实现(顺序队列)如何判断循环队列队满?执行入队操作队列的顺序存储结构及实现(顺序队列)如何判断循环队列队满?执行入队操作队列的顺序存储结构及实现(顺序队列)队空、队满的判定条件出现二义性。
队列的顺序存储结构及实现(顺序队列)链队列:head队列的链式存储结构及实现(链队列)非空链队列front∧队列的链式存储结构及实现(链队列)front∧队列的链式实现队列的链式实现循环队列和链队列的比较pfront。
数据结构综合题参考答案
数据结构综合题参考答案数据结构综合题部分参考答案(仅供参考)⼀、填空1、⼀个算法的效率可分为_____时间_________效率和______空间________效率。
,2、栈的特点是_____先进后出______,队列的特点是_____先进先出________。
、3、在线性表的顺序存储结构中,若每个元素占L个存储单元,则第i个元素ai的存储位置为LOC(ai)=LOC(a1)+ ____(i-1)*L________。
4、已知⼀棵完全⼆叉树共139个结点,按照层次从左到右进⾏编号,根结点编号为1,则编号为60的左孩⼦编号为_____120_________右孩⼦编号为____121__________双亲编号为____30__________。
、、5、已知P为单链表中的⾮⾸尾结点,在P结点后插⼊S结点的语句为:__ s->next=p->next; p-next=s;___。
6、在各种查找⽅法中,平均查找长度与结点个数n⽆关的查法⽅法是______哈希表查找法________。
7、算法时间复杂度的分析通常有两种⽅法,即__事后统计_________和___事前估计________的⽅法,通常我们对算法求时间复杂度时,采⽤后⼀种⽅法。
8、已知元素序列E,F,G,H,I,J,K,L,M,N经过操作XXYXXYXYXYYXXYXYYYXY以后的出栈序列(注X表⽰⼊栈,Y表⽰出栈)_____ FHIJGLMKEN _________。
9、设数组A[1..10,1..8]的基地址为2000,每个元素占2个存储单元,若以⾏序为主序顺序存储,则元素A[4,5]的存储地址为____2056_______;若以列序为主序顺序存储,则元素A[4,5]的存储地址为_2086______。
10、⼀个⼆叉树中叶⼦结点3个,度为1的结点4个,则该⼆叉树共有___9____个结点。
11、在图G的邻接表表⽰中,每个顶点邻接表中所含的结点数,对于⽆向图来说等于该顶点的__度_____,对于有向图来说等于该顶点的____出度_____。
出栈序列相对入栈序列关系 -
出栈序列相对入栈序列关系 -出栈序列相对入栈序列关系在数据结构的定义里,栈是只允许一端进行插入或删除操作的线性表。
人们总结简化为后进先出原则。
栈的定义给定以后引出了另一类问题――出栈序列问题。
就是在给定一个入栈序列(如a1,a2…an)的条件下,在进栈操作时,允许出栈操作,来判断一下哪些序列是可能的出栈序列,而哪些必不是出栈序列。
当然,前提是要保证要求判断的序列里面的元素要与给定入栈序列里的元素一一映射。
否则就没有再往下判断的必要了。
对于这类问题一般的方法是在本子上画表格模拟一个栈然后实际操作一下,看看哪些是可调度实现的,哪些是不可能实现的。
这种方法是很不严谨的,而且工作量很大,对于一个具有n个元素的入栈序列,它的出栈序列有(1/(n+1))*C2nn 种可能。
如果n稍大一点,工作量会颇具规模。
到这来,您也许会有点被忽悠了,其实给定一个如栈序列,a1,a2,……an ,再给定出要判断的出栈队列ai ,aj , ak ,……判断他们是否匹配,很简单,用一个大小为n的数组模拟栈,以a1,a2,……an 做输入,对照着要判断的序列a i ,aj , ak ,…… ,有目的的操作在线性时间内就可以完成。
只是这种操作人工来说稍微麻烦一点罢了。
对于人工做判断,研究发现这类问题是具有一般规律的。
在此先给出这一定律的定义,然后举几个常见的应用,最后给出证明。
这一定律是:在给定入栈顺序序列的前提下,对于其出栈序列里任意元素an ,晚于其出栈且先于入栈的元素必须按入栈的逆序排列。
先后几个应用实例:1.设 a,b,c,d,e,f 以所给的次序进栈,若在进栈操作时,允许出栈操作,则下面得不到的序列为: A. fedcbaB. bcafedC. dcefbaD. cabdef答案是 D .因为 A. B. C 项都满足规律,但 D 项里 a,b 晚于c 出栈且先于 c 入栈,它们的排列顺序应是 ba。
2.元素 a,b,c,d,e 依次进入初始为空的栈中,若元素进栈后可停留,可出栈,直到所有元素都出栈,则在所有可能出栈序列中,以元素d开头的序列个数是多少个?这一问题是可以很方便用上面给的规律来解决。
大学《数据结构》第三章:栈和队列-第一节-栈
第一节栈
一、栈的定义及其运算
1、栈的定义
栈(Stack):是限定在表的一端进行插入和删除运算的线性表,通常将插入、删除的一端称为栈项(top),另一端称为栈底(bottom)。
不含元素的空表称为空栈。
栈的修改是按后进先出的原则进行的,因此,栈又称为后进先出(Last In First Out)的线性表,简称为LIFO表。
真题选解
(例题·填空题)1、如图所示,设输入元素的顺序是(A,B,C,D),通过栈的变换,在输出端可得到各种排列。
若输出序列的第一个元素为D,则输出序列为。
隐藏答案
【答案】DCBA
【解析】根据堆栈"先进后出"的原则,若输出序列的第一个元素为D,则ABCD入栈,输出序列为DCBA
2、栈的基本运算
(1)置空栈InitStack(&S):构造一个空栈S。
数据结构第三章-栈和队列(严蔚敏)
}
s
top
top
…... 栈底 ^
x
24
出栈算法
LinkStack Pop_LinkStack (LinkStack DataType *x) { StackNode *p; if (top= =NULL)return NULL; else {*x = top->data; p = top; top = top->next; top top free (p); a return top;} p } x a top,
11
顺序栈
栈的顺序存储结构简称为顺序栈,是利用一组地址 连续的存储单元依次存放自栈底到栈顶的数据元素,同 时附设指针top指向实际栈顶后的空位置。
12
顺序表和顺序栈的操作区别
以线性表 S= (a1 , a2 , …. , an-1 , an )为例 顺序栈S an+1 高地址 顺序表S 高地址 表尾 an an …… …… S[i] ai ai …… …… a2 低地址 a1 a2 低地址 表头 a1 栈顶top 栈顶top
Stacksize 指示栈的当前可使用的最大容量。栈的初始化操作为: 按设定的初始分配量进行第一次存储分配; base可称为栈底指针,在顺序栈中它始终指向栈底的位置,若 base的值为NULL,则表明栈结构不存在。 top为栈顶指针,其初值指向栈底,即top=base可作为栈空的标 记; 每当插入新的栈顶元素时(入栈),堆栈指针top先压后加 (S[top++]=an+1); ; 删除栈顶元素时(出栈),堆栈指针top先减后弹
B
A
19
顺序栈入栈 int push(SqStack &s, SElemType e){ if (s.top-s.base>=s.stacksize){//栈满的判断 s.base=(SElemTYpe*) realloc(s.base,s.stacksize+ STACKINCREMENT)*sizeof(SElemType)); if (!s.base) exit (OVERFLOW); s.top=s.base+s.stacksize; s.stacksize+=STACKINCREMENT; top } *s.top++=e; //入栈( *s.top=e; *s.top++); return OK; } base
一个栈的入栈序列为123...n,其出栈序列是p1
若已知一个栈的入栈序列一问题:若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为( )解答:则pi为c、n-i+1。
出栈顺序和入栈顺序是反的,所以出栈的第i个元素就是从n开始倒着数的第i个元。
有一个数列(23,45,3,7,3,945)先对其进行进栈操作,则进栈顺序为:23,45,3,7,3,945在对其进行出栈操作,则出栈顺序为:945,3,7,3,45,23 为了方便,通常做到:出栈后不再进栈。
进栈出栈就像一个盒子,先一个个放入盒内,而拿出的时候只有先从上面拿,才能再拿下面。
扩展资料:栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。
它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶。
需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
二若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为( )A、iB、n-iC、n-i+1D、不确定解答p_i=n-i+1.出栈顺序和入栈顺序是反的,所以出栈的第i个元素就是从n开始倒着数的第i个元素.三一个栈的入栈序列为1,2,3,…,n,其出栈顺序是p1,p2,p3,…,pn。
若 p2=3, 则 p3 可能的取值的个数是()A、n-3B、n-2C、n-1D、无法确定第二个出栈的元素为3,那么4,5,6...,n都可以作为第三个出栈的元素,这里就有n-3种情况;如果p1=4,p2=3,接着出栈就会有p3=2;如果p1=2,p2=3,接着出栈就会有p3=1;综上所述,p3不能为3,其他值都可以取,因此一共有n-1种情况。
栈的定义
{
SNODE *p; int x; if( top = = NULL ) { cout<<“栈溢出\n”;x=-1; } else { p = top; top = top-> link ; x = p-> data ; free(p) ; } return x }
(1) 队头指针 front = (front+1)% MAXSIZE ;
(2)队尾指针 rear = (rear +1)% MAXSIZE ;
循环队列队空、队满条件
1 2 3
队空条件 front = rear
0
MAXSIZE-1
front
...rΒιβλιοθήκη ar1 2a2 a3
3
0
a1
...
队满条件(剩下一个位置) front=(rear+1)% MAXSIZE
栈操作举例
TOP
a1 a2 …… 栈底 1.
top=0
(空栈)
an
MAXSIZE
栈顶
2. A B C
top=3 (A、B、C进栈)
3.
A B
top=2 (C出栈)
4. A B C D E F
top=MAXSIZE (栈满)
进出栈序列
有三个元素的进栈序列是1,2,3。写出可能的出 栈序列。
出栈序列
a3
a2 a1 ^ 栈底
算法1-8 进栈操作程序
push(SNODE *top , int x) { SNODE *t; t=new SNODE; if(t = = NULL ) { cout<<“内存中已无可用空间\n”; } else { t -> data = x; t -> link = top; top= t; } }
2023年国家电网招聘之电网计算机综合练习试卷A卷附答案
2023年国家电网招聘之电网计算机综合练习试卷A卷附答案单选题(共40题)1、网络192.168.21.128/26的广播地址为(请作答此空),可用主机地址数( )A.192.168.21.159B.192.168.21.191C.192.168.2l.224D.192.168.21.255【答案】 B2、在Windows 资源管理器中,如果选中某个文件,再按 Delete 键可以将该文件删除,但需要时还能将该文件恢复。
若用户同时按下Delete 和()一组合键时,则可删除此文件且无法从"回收站"恢复。
A.CtrlB.ShiftC.AltD.Alt和Ctrl【答案】 B3、改变路由信息、修改 Windows NT 注册表等行为属于拒绝服务攻击的()方式。
A.资源消耗型B.配置修改型C.服务利用型D.物理破坏型【答案】 B4、某企业 IT 管理员人均可以管理 1500 台设备,故障响应非常快捷,这些设备最有可能是下面哪种()。
A.物理服务器B.虚拟服务器C.虚拟桌面 PCD.物理 PC【答案】 C5、()用来记录对数据库中数据进行的每一次更新操作。
A.后援副本B.日志文件C.数据库D.缓冲区【答案】 B6、循环队列qu的队空条件是()。
A.(qu.rear+1)%MaxSize==(qu.front+1)%MaxSizeB.(qu.rear+1)%MaxSize-=qu.front+1C.(qu.rear+1)%MaxSize==qu.frontD.qu.rear==qu.front【答案】 D7、已知一个线性表为(38,25,74,63,52,48),假定采用H(K)=Kmod7计算散列地址进行散列存储,若利用线性探测的开放定址法处理冲突,则在该散列表上进行查找的平均查找长度为();若利用链地址法处理冲突,则在该散列上进行查找的平均查找长度为()。
A.1.5,1B.1.7,3/2C.2,4/3D.2.3,7/6【答案】 C8、对于长度为m(m>1)的指定序列,通过初始为空的一个栈、一个队列后,错误的叙述是()。
【python刷题】关于一个序列的入栈出栈有多少种方式相关
【python刷题】关于⼀个序列的⼊栈出栈有多少种⽅式相关讲在前⾯剑指offer上有这么⼀道题⽬:题⽬描述输⼊两个整数序列,第⼀个序列表⽰栈的压⼊顺序,请判断第⼆个序列是否可能为该栈的弹出顺序。
假设压⼊栈的所有数字均不相等。
例如序列1,2,3,4,5是某栈的压⼊顺序,序列4,5,3,2,1是该压栈序列对应的⼀个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
(注意:这两个序列的长度是相等的)⽰例1:输⼊[1,2,3,4,5],[4,3,5,1,2]返回值false解题的基本思路:维护⼀个stack和cur:stack⽤于模拟进栈和出栈cur⽤于记录使⽤次数1、对于4,stack:[1,2,3,4]2、对于5,stack:[1,2,3,5]3、对于1,stack:[1,2],此时cur == len(pushV)⽽且1 != 2,返回False具体看代码:popV = [4,3,5,2,1]pushV = [1,2,3,4,5]def IsPopOrder(pushV, popV):stack = []cur = 0for pv in popV:while len(stack) == 0 or pv != stack[-1] and cur < len(pushV):stack.append(pushV[cur])cur += 1if cur == len(pushV) and stack[-1] != pv:return Falseelse:stack.pop()return Trueprint(IsPopOrder(pushV,popV))进⼀步我们想到如果我们能够依此判断⼀个序列是否是以⼀个序列的⼊栈和出栈序列,我们就可以计算⼀个序列的⼊栈和出栈序列有多少种?我们还需要初始序列的全排列,⽐如:[1,2,3]的全排列是:[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]于是我们有了以下代码:popV = [4,3,5,2,1]pushV = [1,2,3,4,5]def permutation(array):def helper(array, tmp):if len(tmp) == len(array):res.append(tmp[:])return resfor i in array:if i in tmp:continuetmp.append(i)helper(array, tmp)tmp.pop()res = []tmp = []helper(array, tmp)return resdef IsPopOrder(pushV, popV):stack = []cur = 0for pv in popV:while len(stack) == 0 or pv != stack[-1] and cur < len(pushV):stack.append(pushV[cur])cur += 1if cur == len(pushV) and stack[-1] != pv:return Falseelse:stack.pop()return Trueprint(IsPopOrder(pushV,popV))res = (permutation(pushV))count = 0for array in res:if IsPopOrder(pushV, array):count += 1print(count)答案是:42借鉴于全排列选择问题的思想,我们是否可以不⽤知道全⽪排列就计算出总数呢?答案也是可以的,⼊栈和出栈就是⼀个选择问题。
出栈序列的研究
收稿日期:2006-12-07基金项目:江苏省高校自然科学研究项目(06K JD520052);江苏技术师范学院数据结构重点课程建设资助项目作者简介:李红卫(1966-),男,山西阳城人,硕士,副教授,主要研究方向为算法、嵌入式软件系统。
出栈序列的研究李红卫,徐亚平(江苏技术师范学院计算机科学与工程学院,江苏常州213001)摘 要:栈是一种非常重要的数据结构,递归、函数调用都离不开栈。
对n 个元素入栈和出栈的研究是栈的一个主要研究内容。
利用二叉树给出了入栈和出栈序列的表示;给出了由前置O 栈序列构造出二叉树的算法;证明了对于按次序入栈的n 个元素,其出栈序列总数为C (2n ,n )/(n +1);对三种求解出栈序列算法进行了分析和研究,并提出一种时间复杂度为O (n )判断某一序列是否为出栈序列的算法,它提高了程序的执行效率。
关键词:出栈序列;Catalan 数;二叉树中图分类号:TP311.12 文献标识码:A 文章编号:1673-629X (2007)10-0127-03Study of Out -Stack SequenceL I Hong 2wei ,XU Ya 2ping(School of Computer Science and Engineering ,Jiangsu Teachers University of Technology ,Changzhou 213001,China )Abstract :Stack is a very important data structure.Recursion and function call cannot get away the stack.Research of the in -stack and the out -stack of n elements is a main content of stack.Expresses the in -stack and the out -stack sequence with binary tree ,gives an al 2gorithm to create a binary tree by pre -O stack sequence ,proves that the number of out -stack sequence is C (2n ,n )/(n +1)when n elements put in the stack in order ,analyzes and studies the three algorithms about solutions of out -stack sequence ,and presents an algo 2rithm ,its time complexity is O (n ),that judges whether some sequence is out -stack sequence.Execution efficiency of the program is improved by the algorithm.K ey w ords :out -stack sequence ;Catalan number ;binary tree0 引 言已知集合N ={1,2,3,…,n},如果按给定的次序1,2,3,…,n 依次入栈,出栈的序列共有多少种?如何给出全部的解?如何判断某一序列是否为出栈序列?对于这几个问题,文献[1~5]对其进行了分析和研究。
有限栈的出栈序列计数问题分析
有限栈的出栈序列计数问题分析王文龙【摘要】出栈序列个数是栈研究的基本问题。
目前的研究大都基于无限栈,即不考虑栈空间的大小来讨论出栈序列计数问题。
但在现实应用中,栈大小往往是有限的,出栈序列问题就要复杂得多。
从非降路径计数的角度,分析了无限栈和有限栈的出栈序列计数问题;从二元函数的角度,给出了出栈序列计数的算法;最后设计出相应的程序进行实现和验证。
实验证明,算法结果正确,算法设计易于理解。
%The stack‐output number is a basic problem of stack research . The present research is mostly based on infinite stack , w hich does not consider the size of the stack , and the stack‐output counts are discussed . But in the practical applications , the size of stack is often limited , the stack‐output probl em has much more complexity . From the perspective of the counting on not descend path , counting problem of limited stack and infinite stack on stack‐output is analysed . And from the perspective of dual function , algorithms are designed . Finally the corresponding programs are designed and verified . T he results show that the algorithm is correct , and the algorithm design is easy to understand .【期刊名称】《西北师范大学学报(自然科学版)》【年(卷),期】2015(000)004【总页数】6页(P46-51)【关键词】有限栈;出栈序列;非降路径【作者】王文龙【作者单位】喀什师范学院信息工程技术系,新疆喀什 844000【正文语种】中文【中图分类】TP311栈是限定仅在表尾端进行插入或删除操作的特殊线性表.通常称表尾端为栈顶,向栈中插入元素称为进栈,从栈中删除元素称为出栈.由于插入和删除运算仅在栈顶一端进行,因此栈具有后进先出的特性,这种特性使得栈有着十分广泛的应用.对一个给定的入栈序列,文献[1-9]对出栈序列的数量等问题进行了研究.然而,以上研究结果均基于无限栈的前提,即栈的大小是不受限制的,也就是栈的大小大于等于入栈序列的长度.而在某些情况下,栈的大小会受到限制,即栈的大小小于入栈序列的长度,此时有限栈的入栈出栈问题会变得较为复杂.因此,文中从非降路径的角度,在栈大小不受限制和栈大小受限制两种情况下,对出栈序列计数问题进行分析研究,并给出计算算法和实现程序.为方便分析,将研究的有关栈的问题描述为:给定入栈序列(1,2,…,n),求出栈序列数量.栈大小不受限制的出栈序列的计数,有多种方法[1-9],文中着重从非降路径计数[10]的角度分析出栈序列的计数问题.不妨设栈长度为入栈序列长度n,此时所有出栈序列的计数,可以用非降路径的计数解决.图1中,若将上行一步看做入栈一个元素,将右行一步看做出栈一个元素,则所有出栈序列的计数等于上三角中从(0,0)到(n,n)的非降路径总数.此时,所求上三角非降路径总数等于(0,0)到(n,n)的方形中从(0,0)到(n,n)的所有非降路径数,减去从(0,0)到(n,n)接触(含穿过)y=x-1上点的所有非降路径数.(0,0)到(n,n)方形中从(0,0)到(n,n)的所有非降路径数为.而从(0,0)到(n,n)接触(含穿过)y=x-1上点的所有非降路径的计数,可考虑将这些非降路径以首次接触y=x-1上的点为界,分为前后两部分.后一部分保持不变,而将前一部分路径做关于y=x-1的对称,产生新的路径.不难发现,新路径与原路径一一对应,而新路径为(1,-1)到(n,n)的矩形中从(1,-1)到(n,n)的所有非降路径数,其值为.因此,上三角中从(0,0)到(n,n)的非降路径总数等于,即为方便后续计算,需要先做如下2个计数.2.1 计数1考虑计算图2由(0,0),(0,t),(s,t),(s-t,0)所组成的直角梯形中,从(0,0)到(s,t)的非降路径总数.此非降路径总数等于(0,0)到(s,t)的矩形中从(0,0)到(s,t)的非降路径总数,减去矩形中从(0,0)到(s,t)接触(含穿过)y=x-(s-t)-1的非降路径总数.矩形中从(0,0)到(s,t)的非降路径总数为对矩形中从(0,0)到(s,t)接触(含穿过)y=x-(s-t)-1的非降路径总数的计数,可以考虑将这些非降路径以首次接触y=x-(s-t)-1上的点为界,分为前后两部分.后一部分保持不变,而将前一部分路径做关于y=x-(s-t)-1的对称,产生新的路径.不难发现,新路径与原路径一一对应,而新路径为(s-t+1,-((s-t)+1))到(s,t)的矩形中从(s-t+1,-((s-t)+1))到(s,t)的所有非降路径数,其值为.因此,由(0,0),(0,t),(s,t),(s-t,0)所组成的直角梯形中,从(0,0)到(s,t)的非降路径总数等于2.2 计数2考虑计算图3由(0,0),(t,t),(s,t),(s-t,0)所组成的平行四边形中,从(0,0)到(s,t)的非降路径总数.此非降路径总数等于(0,0)到(s,t)的直角梯形中从(0,0)到(s,t)的非降路径总数,减去直角梯形中从(0,0)到(s,t)接触(含穿过)y=x+1的非降路径总数.直角梯形中从(0,0)到(s,t)的非降路径总数可由计数1获得,为.而直角梯形中从(0,0)到(s,t)接触(含穿过)y=x+1的非降路径总数的计数,可以将这些非降路径以首次接触y=x+1上的点为界,分为前后两部分.后一部分保持不变,而将前一部分路径做关于y=x+1的对称,产生新的路径.不难发现,新路径与原路径一一对应,而新路径为由(-1,1),(-1,t),(s,t),(s-t+1,1)所组成的直角梯形中从(-1,1)到(s,t)的所有非降路径数,此值可由计数1获得,为.因此,由(0,0),(t,t),(s,t),(s-t,0)组成的平行四边形中,从(0,0)到(s,t)的非降路径总数等于即2.3 栈大小受限制的出栈序列计数当栈的大小为k,小于入栈序列长度n时,栈中元素不能超过k个,则出栈序列的计数对应于图4上三角中从(0,0)到(n,n)不穿过y=x+k上点的非降路径数,即图4上三角中从(0,0)到(n,n)被y=x和y=x+k所夹的非降路径总数.此时所求的非降路径总数等于上三角中从(0,0)到(n,n)的非降路径总数,减去上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的路径总数.上三角中从(0,0)到(n,n)的非降路径总数由前文可知为.现需计算上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的非降路径总数.为求其值,结合非降路径的特点,在图5中,可以考虑求出接触(含穿过)a1点的非降路径总数、不接触a1点而接触(含穿过)b1点的非降路径总数……依次类推,直到求出不接触d1点之前的点而接触(含穿过)d1点的非降路径总数,然后将所求的非降路径总数求和,即为上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的非降路径总数.为求上述的每个非降路径总数,可以考虑从y=x+k上的点上行到达y=x+k+1上的点,例如,接触(含穿过)a1点的非降路径,可以先从(0,0)到达a点,然后上行到达a1点,最后再到达(n,n)点,这些非降路径总数的值为由a1,(0,n),(n,n),(k+1,k+1)组成的直角梯形中从a1到(n,n)的非降路径总数.其值可由计数1获得,为.不接触a1点而接触(含穿过)b1点的非降路径,可以先从(0,0)到达b点,然后上行到达b1点,最后再到达(n,n)点.这些非降路径分为两部分,一部分为由(0,0),a,b,(1,1)组成的平行四边形中从(0,0)到达b点的非降路径,另一部分为由b1,(1,n),(n,n),(k+2,k+2)组成的直角梯形中从b1到达(n,n)的非降路径.前一部分平行四边形中从(0,0)到达b点的非降路径总数可由计数2获得,为;而后一部分非降路径总数可由计数1获得,为.所求的不接触a1点而接触(含穿过)b1点的非降路径总数为这两部分之积考虑一般情况下,不接触c1点之前的点而接触(含穿过)c1点的非降路径,可以先从(0,0)到达c点,然后上行到达c1点,最后再到达(n,n)点.这些非降路径分为两部分,一部分为由(0,0),a,c,(i,i)组成的平行四边形中从(0,0)到达c点的非降路径,另一部分为由c1,(i,n),(n,n),(k+1+i,k+1+i)组成的直角梯形中从c1到达(n,n)的非降路径.前一部分平行四边形中从(0,0)到达c点的非降路径总数可由计数2获得,为;而后一部分非降路径总数可由计数1获得,为不接触c1点之前点而接触(含穿过)c1点的非降路径总数为这两部分之积不难发现,当i=0时,此式变为,与接触(含穿过)a1点的非降路径总数相同.当i=1时,与不接触a1点而接触(含穿过)b1点的非降路径总数相同.因此此式即为所求的依次接触(含穿过)y=x+k+1上点的非降路径总数的通项公式.式中i的取值范围由y=x+k上的a,b,…,d所有点的个数决定,而由于d点的纵坐标为(n-1),所以d点的横坐标为(n-k-1),因此i的取值范围为0~(n-k-1).由此,可得在上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的非降路径总数等于该式可化简为根据以上分析,上三角中从(0,0)到(n,n)被y=x和y=x+k所夹的非降路径总数为此值即为当栈的大小为k,小于入栈序列长度n时,出栈序列的计数.2.4 几种特殊情况下的计数2.3节中所得计数公式较为复杂,可以考虑以下几种较特殊的情况下的计数问题. 1)当-1时,由2.3节中分析可知,图6出栈序列的计数等于上三角中从(0,0)到(n,n)的非降路径总数,减去上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的路径总数.计算上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的非降路径总数,可以考虑将这些非降路径以首次接触y=x+k+1上的点为界,分为前后两部分.后一部分保持不变,而将前一部分路径做关于y=x+k+1的对称,产生新的路径.不难发现,新路径与原路径一一对应.而新路径所在图形形状需考虑k+1与n-(k+1)的大小关系,当k+1≥n-(k+1),即-1时,上三角中从(0,0)到(n,n)接触(含穿过)y=x+k+1上点的非降路径一一对应于图6中由(-(k+1),k+1),(-(2k-n+2),n),(n,n),(k+1,k+1)组成的平行四边形中从(-(k+1),k+1)到(n,n)的非降路径总数.该非降路径总数可由计数2获得,为则上三角中从(0,0)到(n,n)被y=x和y=x+k所夹的非降路径总数为此式可以化简为此值即为当-1时,栈大小受限时的出栈序列的计数.分析上式,当k=n-1时,值为当k=n-2时,值为2)当k=1时,不难发现出栈序列只有一种.3)当k=2时,出栈序列的计数对应于图7上三角中从(0,0)到(n,n)被y=x和y=x+2所夹的非降路径总数.此时求非降路径总数,可以做如下考虑.所求的非降路径先由(0,0)到a,而后由a 到b,再到c……直到e,最后由e到(n,n).由(0,0)到a只有1种选择,而a到b有2种选择,b到c有2种选择……到e有2种选择,e到(n,n)只有1种选择.根据乘法法则可知,上三角中从(0,0)到(n,n)被y=x和y=x+2所夹的非降路径总数等于2n-1,此即当k=2时,栈大小受限时的出栈序列的计数.为更好地计算出栈序列数量,从求二元函数值的角度,设计两种情况下出栈序列计数的算法及改进算法,并给出相应的程序实现.3.1 栈大小不受限制可以把问题描述为求一个二元函数f(x,y)的值,其中x表示待入栈元素个数,y表示已在栈中元素个数.对栈的操作不外乎两种:继续入栈一个元素,则此时待入栈元素个数变为x-1,栈中元素个数变为y+1;出栈一个元素,则此时待入栈元素个数不变为x,栈中元素个数变为y-1.用函数表示为f(x,y)=f(x-1,y+1)+f(x,y-1).再考虑x=0和y=0两种特殊情况.当x=0时,则元素都在栈中,此时出栈序列数量为1,即f(0,y)=1;当y=0时,栈中无元素,此时只能入栈一个元素,待入栈元素个数为x-1,栈中元素个数为1,即f(x,0)=f(x-1,1).此时,所求问题变为求函数f(n,0)的值.根据以上分析,可采用递归函数解决计数问题.程序如下:#include “iostream.h”int stacknum(int x,int y){ if(x==0) return 1;if(y==0) return stacknum(x-1,1);return stacknum(x-1,y+1)+stacknum(x,y-1);}void main(){ int x,y;cout<<“please input x and y:”<<endl;cin>>x>>y;cout<<stacknum(x,y)<<endl;}考虑到递归效率不高,可以对程序进行改进.用二维数组s[i][j]来记录函数f(i,j)的值,则s[i][j]=s[i-1][j+1]+s[i][j-1].而当i=0时,s[0][j]=1;当j=0时,s[i][0]=s[i-1][1].由此可以得到如下效率更高的程序:#include “iostream.h”#define N 100void inits(int x,int s[N][N]){ int i,j;for(i=0;i<=x;i++)for(j=0;j<=x;j++){ if(i==0) s[i][j]=1; else if(j==0) s[i][j]=s[i-1][1];else s[i][j]=s[i-1][j+1]+s[i][j-1];}}void main(){ int x,y,s[N][N]; cout<<“please input x and y:”<<endl;cin>>x>>y;inits(x,s);cout<<s[x][y]<<endl;}3.2 栈大小受限制假设栈的大小为k,由3.1节可知,当y<k时,f(x,y)=f(x-1,y+1)+f(x,y-1);当y=k时,f(x,y)=f(x,y-1);当x=0,y≤k时,f(0,y)=1;当y=0时,f(x,0)=f(x-1,1).可采用递归函数解决计数问题,程序如下:#include “iostream.h”int k;long stacknum(int x,int y){ if((x==0)&&(y<=k)) return 1L;if(y==0) return stacknum(x-1,1);if(y==k) return stacknum(x,y -1); return stacknum(x-1,y+1)+stacknum(x,y-1);}void main(){ int n,m;cou t<< “please input x y and k:”<<endl;cin>>x>>y>>k;cout<<stacknum(x,y)<<endl;}亦可用二维数组记录函数值,程序如下:#include “iostream.h”#define N 100int k;void inits(int x,int s[N][N]){ int i,j;for(i=0;i<=x;i++)for(j=0;j<=k;j++){ if(i==0) s[i][j]=1; else if(j==0) s[i][j]=s[i-1][1]; else if(j==k) s[i][j]=s[i][j-1]; else s[i][j]=s[i-1][j+1]+s[i][j-1];}}void main(){ int x,y,s[N][N];cout<<“please input x y and k:”<<endl;cin>>x>>y>>k;inits(x,s); cout<<s[x][y]<<endl;}【相关文献】[1] 张先伟,曹雁锋.用插入法解决堆栈输出问题[J].计算机应用与软件,2007,24(11):169-171.[2] 唐锐.用后继序列法解决堆栈输出问题[J].小型微型计算机系统,2006,27(12):2314-2316.[3] 徐凤生.出栈序列的性质及其求解新算法[J].计算机工程与应用,2006,42(5):66-68.[4] 何坤金,陈正鸣,杨垠.基于算子的栈序列生成算法与实现[J].计算机工程与设计,2006,27(12):2266-2267.[5] 唐保祥.栈序列及其生成算法[J].郑州大学学报:自然科学版,2001,33(4):33-35.[6] 李红卫,徐亚平.出栈序列的研究[J].计算机技术与发展,2007,17(10):127-129.[7] 袁红娟.基于链表的出栈序列生成算法[J].河北北方学院学报:自然科学版,2006,22(5):71-75.[8] 韩静.“数据结构”课程中出栈序列的一种求解算法[J].计算机教育,2008,6(23):68-70.[9] 吴集林.用二叉树解决出栈序列问题[J].赣南师范学院学报:自然科学版,2005,26(6):28-30.[10] 卢开澄,卢华明.组合数学[M].第4版.北京:清华大学出版社,2006:128-130.。
2025届信息技术一轮复习练习:专题14 栈(含答案)
专题14栈知识点一栈的性质的出栈顺序是()1.数字1,2,3依次进栈,则不可能...A.3,2,1B.3,1,2C.1,2,3D.2,1,32.有一个空栈,规定用Ⅰ表示一个元素入栈,用O表示一个元素出栈。
现经过IIOIOOIO系列操作后,元素的出栈顺序是4,1,3,2,则元素的入栈顺序是() A.1,3,4,2 B.3,4,1,2C.2,3,1,4D.1,4,3,23.有1个栈,从栈顶到栈底依次为元素a、b、c,并且已知元素d已入栈并出栈,则这四个元素的入栈顺序可能为()A.a,b,c,dB.b,d,c,aC.c,d,b,aD.d,a,b,c4.某栈初始状态为空,有五个元素的入栈序列为a,b,c,d,e,每个元素都只能进行1次入栈和1次出栈操作,若第1个出栈的元素是c,则以下推测正确的是()A.第2个出栈的元素肯定是bB.最后1个出栈的元素肯定是aC.第2个出栈的元素肯定不是dD.最后1个出栈的元素肯定不是b5.下列关于数据结构的说法正确的是()A.栈结构只允许从栈底入栈,从栈顶出栈B.链表结构只能使用二维列表存储C.某完全二叉树有偶数个节点,则一定存在度为1的节点D.数组是一种适合用于组织、存储涉及频繁插入与删除的数据结构6.假设有一个栈和一个队列,它们的初始状态均为空。
元素ABCDEFGH依次进入栈中,每个元素出栈后就立即进入队列中。
如果队列中元素的出队顺序是CGFEHDBA,则栈的容量至少是()A.4B.5C.6D.77.元素p,y,t,h,o,n,s按序入栈,从所有出栈序列中(要求元素全部出栈),以元素n开头且以元素p结尾的出栈序列的数量有()A.3B.4C.5D.6的是()8.若一个序列的入栈顺序为1,2,3,4,5,则其出栈顺序不可能...A.1,2,3,4,5B.4,5,3,2,1C.4,3,5,1,2D.3,2,1,5,49.用一个带盖的玻璃筒来放取乒乓球,放、取只能在带盖的一端进行(另一端为封闭状态),且筒的直径只允许一个乒乓球进出。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
出栈序列相对入栈序列关系在数据结构的定义里,栈是只允许一端进行插入或删除操作的线性表。
人们总结简化为后进先出原则。
栈的定义给定以后引出了另一类问题——出栈序列问题。
就是在给定一个入栈序列(如a1,a2…a n)的条件下,在进栈操作时,允许出栈操作,来判断一下哪些序列是可能的出栈序列,而哪些必不是出栈序列。
当然,前提是要保证要求判断的序列里面的元素要与给定入栈序列里的元素一一映射。
否则就没有再往下判断的必要了。
对于这类问题一般的方法是在本子上画表格模拟一个栈然后实际操作一下,看看哪些是可调度实现的,哪些是不可能实现的。
这种方法是很不严谨的,而且n 种工作量很大,对于一个具有n个元素的入栈序列,它的出栈序列有(1/(n+1))*C2n可能。
如果n稍大一点,工作量会颇具规模。
到这来,您也许会有点被忽悠了,其实给定一个如栈序列,a1,a2,……a n ,再给定出要判断的出栈队列a i ,a j , a k,……判断他们是否匹配,很简单,用一个大小为n的数组模拟栈,以a1,a2,……a n 做输入,对照着要判断的序列a i ,a j , a k,…… ,有目的的操作在线性时间内就可以完成。
只是这种操作人工来说稍微麻烦一点罢了。
对于人工做判断,研究发现这类问题是具有一般规律的。
在此先给出这一定律的定义,然后举几个常见的应用,最后给出证明。
这一定律是:在给定入栈顺序序列的前提下,对于其出栈序列里任意元素a n ,晚于其出栈且先于入栈的元素必须按入栈的逆序排列。
先后几个应用实例:1.设a,b,c,d,e,f 以所给的次序进栈,若在进栈操作时,允许出栈操作,则下面得不到的序列为:A. fedcbaB. bcafedC. dcefbaD. cabdef答案是 D .因为 A. B. C 项都满足规律,但 D 项里a,b 晚于c 出栈且先于 c 入栈,它们的排列顺序应是ba。
2.元素a,b,c,d,e 依次进入初始为空的栈中,若元素进栈后可停留,可出栈,直到所有元素都出栈,则在所有可能出栈序列中,以元素d开头的序列个数是多少个?这一问题是可以很方便用上面给的规律来解决。
序列以元素d开头说明d是第一个出栈的。
a,b,c要晚于d出栈同时a,b,c对先于d入栈,所以根据上面的规律a,b,c,d的排列顺序只能是dcba。
除了元素d 的前面e还可以有4个位置可取,所以答案是4种。
3.给定一个正整数元素序列1,2,3,…,99,100.允许进栈,退栈操作交替进行,我们根据已给的规律很容易判别。
1,2,…,7,10,3,11,12,6,…,97,98,99,100不是出栈序列,因为7,3,6.不符合规律。
下面给出定律的证明。
假设给定一个元素序列a1,a2,a3, …,an(记为Sa)以所给的次序依次进栈,在进栈操作时,允许出栈操作。
则判断另一个已知序列元素一一映射序列记为Sb可否成为原序列的充分必要条件是:对于序列Sb 里的任意元素ak,相应于Sa里排在其前面的且在Sb里排在其后面的所有元素按与Sa对应相反的顺序排列。
已知序列Sk , x1,x2…xi,xn(i∈I且1<=i<=n)对于任意三个整数1<=i<j<k<=n有Ni<max(xj,xk)或xi>xj>xk假设序列里有一元素xi,其右面的小于其元素值的元素不都严格递减即存在j,k i<j<k xi>max(xj,xk)X i <Xk可知这三个元素既不符合xi<max(xj,xk)也不符合xi>xj>xk,即也与题设矛盾,由此可知,结论正确。
必要性证明:对于Sa里的任意三个元素,ai,aj,ak,它们在Sa里的排列顺序是ai,aj,ak,如果在Sb里的排列顺序变为ak,ai,aj,假设序列Sb是Sa的出栈序列。
根据栈的性质,和ai,aj,ak三个元素分别在Sa和Sb里的位置关系克制,为ak在栈顶时,ai,aj一定在栈里,是aj比ai更靠近栈顶。
根据Sb里ak,ai,aj的位置关系知Sk是先出栈的如果ak出栈后,ai先于aj 出栈,这与栈只允许在一端进行插入或删除的操作自相矛盾。
充分性证明:对于序列Sa我们只关心其序列里各元素的对应位置关系,不考虑其它属性。
为表述方便我们把元素a1,a2,a3…an-1,an,对映抽象为1,2,3,…,n-1,n(数值越大,表示其排列越靠后,即入栈越晚)记为Sd。
对于序列Sb,x1,x2,x3,…,xn,里面的元素与Sd一一映射,且xi的下标值i的大小代表其在Sb的位置情况,数值越大越靠后,即出栈越晚。
如果对于任意三个整数1<=i<j<k<=n,xi,xj,xk满足xi<max(xj,xk)或xi>xj>xk(即如果xi>max(xj,xk)必须同时有xi>xk)。
来讨论一下。
我们以I代表入栈操作。
0代表出栈操作。
<1>当xi<max(xj,xk)时,1)假设xi,xj,xk相邻,即k-j=j-i=1xi,xj,xk三个元素大小关系全排列有3!=6种,这里符合要求的有四种分别为xi<xj,xi<xk,xj<xk x的对应值由小到大排列xi<xj<xkxi<xj,xi<xk,xj>xk xi<xk<xjxi<xj,xi>xk,xj>xk xk<xi<xjxi>xj,xi<xk,xj<xk xj<xi<xk因为x的值与Sd里面的整数是一一映射关系,而Sd里面的整数是Sa里面相对位置上的元素是一一对应的。
所以xi,xj,xk的大小关系就是他们所对应的,整数所对应的Sa里面的元素的位置关系。
可根据以上分析可求得xi,xj,xk所间接对应到的Sa里元素的位置关系。
以xi’,xj’,xk’表示其间接对应元素,可得以上四种情况分别的入栈顺序。
而且我们都可以让他们经过栈后实现xi’,xj’,xk’的排列xi’,xj’xk’对应出栈入栈操作方法Ixi’Oxi’Ixj’Oxj’Ixk’Oxk’xi’,xk’xj’Ixi’Oxi’Ixk’Ixj’Oxj’Oxk’xk’,xi’xj’Ixk’Ixi’Oxi’Ixj’Oxj’Oxk’xj’,xi’xk’Ixj’Ixi’Oxi’Oxj’Ixk’Oxk’所以,如果xi<max(xj,xk)且xi,xj,xk相邻,我们是可以调度期间接对应到的Sa内的元素来实现符合相应顺序的出栈序列。
2)假设xi,xj,xk不都相邻…xi…xj…xk…在xi<max(xj,xk)的前提下,他们的大小关系还是有以上那四种情况。
xi<xj<xkxi<xk<xjxk<xi<xjxj<xi<xk它们的间接对应元素为…xi’…xj’…xk’……xi’…xk’…xj’……xk’…xi’…xj’……xj’…xi’…xk’…在保证除xi’xj’xk’以外的元素正确调度的前提下,我们依然可以按…Ixi’…Oxi’…Ixj’…Oxj’…Ixk’…Oxk’……Ixi’…Oxi’…Ixj’…Oxj’…Ixk’…Oxk’……Ixk’…Ixi’…Oxi’…Ixj’…Oxk’…Oxk’……Ixj’…Ixi’…Oxi’…Oxj’…Ixk’…Oxk’…的调度方法保证其实现…xi’…xj’…xk’的排列。
所以如果xi<max(xj,xk),不论xi,xj,xk相邻与否都可以调度期间接对应到的Sa内的元素以固定的相同顺序出栈,得到…xi’…xj’…xk’…的出栈顺序。
2>当xi>xj>xk时(即,xi>max(xj,xk),则xj>xk)1)假设xi,xj,xk相邻,即k-1=j-i=1分别以xi’,xj’,xk’表示xi,xj,xk的间接对应元素,由xi>xj>xk可知它们的入栈顺序是:Xk’xj’,xi’可以由Ixk’Ixj’Ixi’Oxi’Oxj’Oxk’来实现出栈序列按xi’,xj’,xk’排列。
所以知,如果xi>xj>xk且xixjxk相邻,可以调度其间接对应到Sa的元素,以固定顺序入栈得到xi’xj’xk’的出栈序列。
2)当xi,xj,xk不都相邻时…xi…xj…xk…在xi>xj>xk的前提下保证其它元素可正确调度,还可以按…Ixk’…Ixj’…Ixi’…Oxi’…Oxj’…Oxk’…得到…xi’…xj’…xk’的出栈序列。
所以,如果xi>xj>xi,不论xi,xj,xk相邻与否,都可以调度其间接对应到Sa内的元素,以固定顺序入栈,而得到…xi’…xj’…xk’…的出栈序列。
综合1,2可知对于已知的入栈序列到Sa,a1,a2, …an,序列Sb里面的元素与Sa一一映射如果Sb里的任意元素ak,相应于Sa里排在ak前面,且在Sb里排在ak后面的所有元素,按与在Sa里的相反顺序排列,就可以断定Sb里Sa的入栈序列。
综述可知,这是个充要条件。