线性表——栈,队列,链表
一.栈
栈(stack)(last in first out);后进先出
1.函数实现栈
#include<cstdio>
using namespace std;
int s[10005];
int tot;
void push(int x)
{
s[++tot]=x;
}
void pop()
{
tot--;
}
void print()
{
for(int i=1;i<=tot;i++)
printf("%d ",s[i]);
puts("");
}
void top()
{
printf("top=%d\n",s[tot]);
}
int main(void)
{
push(1);
print();
top();
push(2);
print();
top();
push(3);
print();
top();
pop();
print();
top();
pop();
print();
top();
pop();
print();
return 0;
}
输出:
1
top=1
1 2
top=2
1 2 3
top=3
1 2
top=2
1
top=1
2.宏定义实现栈
int s[10005],tot=0;
#define push(x) s[++tot]=x
#define pop tot--
#define size tot
#define top s[tot];
3.STL实现栈
STL中的stack无法随机访问
#include<stack>
#include<cstdio>
using namespace std;
stack<int>s;
int main()
{
s.push(10);
printf("top=%d\n",s.top());
s.push(20);
printf("top=%d\n",s.top());
s.push(30);
printf("top=%d\n",s.top());
printf("size=%d\n",s.size());
while(!s.empty())
{
printf("%d ",s.top());
s.pop();
}
puts("");
return 0;
}
例题1:P1241 括号序列
P1241 括号序列
题目描述
定义如下规则序列(字符串):
1.空序列是规则序列;
2.如果S是规则序列,那么(S)和[S]也是规则序列;
3.如果A和B都是规则序列,那么AB也是规则序列。
例如,下面的字符串都是规则序列:
(),[],(()),([]),()[],()[()]
而以下几个则不是:
(,[,],)(,()),([()
现在,给你一些由‘(’,‘)’,‘[’,‘]’构成的序列,你要做的,是补全该括号序列,即扫描一遍原序列,对每一个右括号,找到在它左边最靠近它的左括号匹配,如果没有就放弃。在以这种方式把原序列匹配完成后,把剩下的未匹配的括号补全。
输入格式
输入文件仅一行,全部由‘(’,‘)’,‘[’,‘]’组成,没有其他字符,长度不超过100。
输出格式
输出文件也仅有一行,全部由‘(’,‘)’,‘[’,‘]’组成,没有其他字符,把你补全后的规则序列输出即可。
输入输出样例
输入 #1
([()
输出 #1
()
说明/提示
将前两个左括号补全即可。
在这里插入代码片
例题2:P1449 后缀表达式
P1449 后缀表达式
题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
如:3*(5–2)+7对应的后缀表达式为:3.5.2.-*7.+@。’@’为表达式的结束符号。‘.’为操作数的结束符号。
输入格式
输入:后缀表达式
输出格式
输出:表达式的值
输入输出样例
输入 #1
3.5.2.-*7.+@
输出 #1
16
说明/提示
字符串长度,1000内。
二.队列
队列:first in first out 先入先出。
实现队列
int s[10005],fnt,end;
#define push(x) s[++end]=x
#define pop fnt++
#define front s[fnt]
#define size end-fnt+1
例题1.约瑟夫问题
题目描述
n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.
输入格式
n m
输出格式
出圈的编号
输入输出样例
输入 #1
10 3
输出 #1
3 6 9 2 7 1 8 5 10 4
使用队列来做
#include<queue>
#include<cstdio>
#include<iostream>
using namespace std;
queue<int>q;
int n,k;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
q.push(i);
int now=1;
while(!q.empty())
{
if(now==k)
{
cout<<q.front()<<" ";
q.pop();
now=1;
}
else {
q.push(q.front());//实现环
q.pop();
now++;
}
}
cout<<endl;
return 0;
}
公式法,求最后留下来的人
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e6+5;
ll n,k,cnt;
int main()
{
cin>>n>>k;
for(ll i=1;i<=n;i++)\
cnt=(cnt+k)%i;
cout<<cnt+1<<endl;
return 0;
}
三.双端队列
#include<stack>
#include<iostream>
using namespace std;
deque<int>d;
int main()
{
d.push_front(1);//前
d.push_back(10);//后
cout<<d.front()<<endl;
cout<<d.back()<<endl;
cout<<d[0]<<endl;//支持随机访问(下标访问)但是复杂度很高O(n);
cout<<d[1]<<endl;
d.pop_front();
d.pop_back();
return 0;
}
输出:
1
10
1
10