兩種數據結構。
1.棧
先進後出,類似一個桶,向裏面丟東西,先拿出來的是晚丟進去的
支持棧頂插入刪除,查詢棧大小和是否爲空
STL中:stack
用於dfs
手寫棧:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
int n,t,x,tot = 0;
int num[MAXN];
void push(int x){
tot ++;
num[tot] = x;
return;
}
void pop(){
tot --;
return;
}
bool empty(){
if(tot == 0) return true;
else return false;
}
void init(){
memset(num,0,sizeof(num));
tot = 0;
return;
}
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; i ++){
scanf("%d",&t);
if(t == 1) {
scanf("%d",&x);
push(x);
}
else if(t == 2){
if(!empty()) pop();
else {
puts("impossible!");
return 0;
}
}
else if(t == 3) printf("%d\n",num[tot]);
}
// if(empty()) puts("impossible!");
// else printf("%d\n",num[tot]);
return 0;
}
2.隊列
先進先出,類似排隊,先排的人先走
支持隊首插入刪除,查詢隊大小和是否爲空
用於bfs
手寫隊列:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
int n,t,x,l = 1,r = 1,tot = 0;
int num[MAXN];
void push(int x){
num[r] = x;
r ++;tot ++;
return;
}
void pop(){
l ++;tot --;
return;
}
bool empty(){
if(tot == 0) return true;
else return false;
}
void init(){
memset(num,0,sizeof(num));
tot = 0;
return;
}
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; i ++){
scanf("%d",&t);
if(t == 1) {
scanf("%d",&x);
push(x);
}
else if(t == 2){
if(empty()){puts("impossible!"); return 0;}
else pop();
}
else if(t == 3) printf("%d\n",num[l]);
}
// if(empty()) puts("impossible!");
// else printf("%d\n",num[l]);
return 0;
}
循環隊列:
訪問到隊尾後,下一個訪問隊首
類似手環,首尾相連
實現中判斷位置,隊尾了就回到隊首
或者取膜 %%%
雙端隊列:
支持隊首隊尾的查詢插入刪除 && 隊列大小及是否爲空
3.單調棧和單調隊列
保證內部元素單調 從大到小或者從小到大
每次插入,檢驗插入後是否維持單調,不行就刪
比如原先爲1 3 5 想插入2
發現2 < 5 彈出5 原序列變爲 1 3
發現2 < 3 彈出3 原序列變爲 1
發現2 > 1 插入2 原序列變爲 1 2
維護單調
應用於DP優化
實質是每個元素的價值從大到小,時效性從小到大