[数据结构]第三章

您所在的位置:网站首页 stacktop(s) [数据结构]第三章

[数据结构]第三章

2024-06-30 15:37:33| 来源: 网络整理| 查看: 265

栈是一种特殊的表,只在表首进行插入和删除操作(表首->栈顶;表尾->栈底)(后进先出表/LIFO表)

·支持的运算:

1.StackEmpty(S):栈S是否为空(top = -1) 2.StackFull(S): 栈S是否已满 3.StackTop(S):返回栈S的栈顶元素 4.Push(x,S):元素x入栈 5.Pop(S):删除并返回栈顶元素

·应用实例:

0.后缀算术表达式求值

这里写图片描述 这里写图片描述 这里写图片描述 这里写图片描述 这里写图片描述

·关于ADT栈模型的思考题:

1.车皮编序问题: 这里写图片描述 按顺序进站,出站的轨道最多能得到多少种不同的车皮编排方案。 例如,当n=3时,最多得到5组:123,132,213,231,321

考虑对于j属于1~n中的一个数,若在此刻j要出站,那么前j-1要都出去,有B(j-1)种可能。B(n) = ∑B(j-1)*B(n-j) = 1/(n+1)×C(2n,n) (卡特兰数)

2.亲兄弟问题:

给定一个序列,输出对于每个元素i之后最近的一个不小于它的元素位置,不存在则输出-1 如序列:6,1,4,3,6,2,4, 7,3, 5 输出:   4,2,4,4,7,6,7,-1,9,-1

思路:遍历序列依次入栈,当元素i入栈时发现栈顶元素不大于它,那么此栈顶元素的亲兄弟即i,弹出栈顶元素,直到不能再更新栈后把元素i入栈。最后留在栈内没有元素来更新的则为-1。 代码:

for(int i = 0; i < n; i++) { tmp.id = i; scanf("%d",&tmp.num); while(top >= 0 && tmp.num >= stack[top].num) { ans[stack[top].id] = i; top--; } stack[++top] = tmp; } while(top>=0) { ans[stack[top].id] = -1; top--; } for(int i = 0; i < n; i++) printf("%d ",ans[i]);

//–作业题

3.2 文档

(第一次被选中优秀作业的一题代码,咿呀好开心///)

这里写图片描述

(input入栈后有两种操作,一个是撤销,能撤销最后一次输入的字符或撤销一次恢复;另一个是恢复,能够恢复最后一次的撤销操作。可以视作每次的撤销都是把这个字符串压入一个缓存栈,恢复则是从缓存栈中弹回到原来的栈。当遇到input时恢复失效,那么就清空缓存栈。最后输出的时候因为还是遵循先入先出,所以把原栈中先弹出到另一个空栈再挨个输出。)

#include #include #include #include #include using namespace std; stack preStack; stack aftStack; char op[15]; char word[35]; void clear() { while(!aftStack.empty()) aftStack.pop(); } void print() { clear(); while(!preStack.empty()) { aftStack.push(preStack.top()); preStack.pop(); } printf("%s",aftStack.top().c_str()); aftStack.pop(); while(!aftStack.empty()) { printf(" %s",aftStack.top().c_str()); aftStack.pop(); } } int main() { int n; scanf("%d",&n); while(n--) { scanf("%s",op); if(op[0] == 'i') { scanf("%s",word); preStack.push(word); //清空缓存栈 clear(); } else if(op[0] == 'c') { if(op[5] == 'z') { if(!preStack.empty()) { string str = preStack.top(); preStack.pop(); aftStack.push(str); } } else if(op[5] == 'y') { if(!aftStack.empty()) { string str = aftStack.top(); aftStack.pop(); preStack.push(str); } } } } if(preStack.empty()) printf("No output\n"); else print(); return 0; }

3.3 最大最小

这里写图片描述

(不明就里地偷看惹泡泡的代码嘤嘤嘤。) (思路是,由于题目中只做加法和乘法,可以发现先把加法全做了在把这些和相乘为最大,先把乘法做完再把所有乘积相加最小。所以用两个栈,一个储存和一个储存乘积。)

#include #include #define LL __int64 #define MAX 200 #define MOD 870764322 using namespace std; LL add[MAX+10]; LL mul[MAX+10]; int aTop = 1; int mTop = 1; int main() { int num; char op; scanf("%d",&num); add[aTop] = num; mul[mTop] = num; while(cin >> op >> num) { if(op == '+') { add[aTop] = (add[aTop]+num)%MOD; mul[++mTop] = num; } else { mul[mTop] = (mul[mTop]*num)%MOD; add[++aTop] = num; } } LL Max = 1; LL Min = 0; while(aTop) Max = (Max*add[aTop--])%MOD; while(mTop) Min = (Min+mul[mTop--])%MOD; printf("%I64d\n%I64d",Max,Min); }

3.1 火车

这里写图片描述

(模拟。sIn模拟中转栈的情况,用flag记录火车进出中转栈。每次从in数组中拿出第一个火车进栈,看是否与sOut数组的栈顶相同,若相同则出栈。最后看sOut数组中是否已全部出栈,若已全部出栈则根据flag中的记录输出in/out)

#include #include using namespace std; char in[15]; char sIn[15]; char sOut[15]; bool flag[30]; //1为in 0为out int i; int cnt = 0; int main() { int n; scanf("%d %s %s",&n,in,sOut); int iTop = -1; int sTop = 0; for(i = 0; i < n; i++) { sIn[++iTop] = in[i]; flag[cnt++] = 1; while(sIn[iTop] == sOut[sTop]) { flag[cnt++] = 0; iTop--; sTop++; if(sTop == n) break; } } if(sTop != n) printf("No\n"); else { printf("Yes\n"); for(i = 0; i < 2*n; i++) { if(flag[i]) printf("in\n"); else printf("out\n"); } } return 0; }

3.4 价值

这里写图片描述

(单调栈。如果确定区间然后在区间内求最小这样是O(n^3),如果以某点为最小然后向左向右延伸这样是O(n^2),利用单调栈可以把复杂度控制在O(n)。这里维护的是一个从栈底到栈顶单调递增的栈,当元素大于栈顶时入栈;当元素小于栈顶时,栈顶元素依次出栈直到栈顶不大于该元素。  考虑对第i个元素能够向左向右延伸的位置lef和rig,开始的时候每个元素延伸范围都是本身i,当有元素要出栈时,说明i元素小于这个出栈元素,出栈元素所能向左延伸到的地方i元素也能延伸到,于是a[i].lef = stack[pen].lef,这样在入栈找好位置之后i元素向左延伸的位置就确定了下来。同时由于是递增栈,这个栈内的每个元素所能向右延伸的位置都是栈顶元素右延伸的位置。并且,当元素应要出栈的时候,说明它遇到了一个在它右侧且比它小的元素,也就是已经没可能更新它的延伸范围了,这时候计算下以它为最小的范围区间内val以更新maxval。第n+1个元素给它赋值-1是为了最后用来弹出所有的栈内元素一一计算。   最后注意下ai很大会爆int。)

#include #include using namespace std; #define LL __int64 #define MAX 100000 struct num { int val; int lef; int rig; }a[MAX+10],stack[MAX+10]; LL myMax(LL a, LL b) { return a>b?a:b; } LL sum[MAX+10]; int top = 0; int i; LL maxval = -MAX; LL cal(int l,int r, int minnum) { return (LL)minnum*(sum[r]-sum[l]+a[l].val); } int main() { int n; scanf("%d",&n); for(i = 1; i 0 && a[i].val


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭