文章目录
栈
- 栈是一种操作受限的线性表只允许从一端插入和删除数据。
栈的实现(1):
STL中的stack:
- 定义:stack<数据类型> P(变量名);
- 插入x: P.push(x);
- 返回栈顶元素:P.top();
- 删除栈顶元素:P.pop();
- 判断栈是否为空:P.empty(),为空返回1
- 栈的大小:P.size();
栈的实现(2):
//数组模拟:
int P[N], top;
void init()// 初始化
{
top = -1;
}
void pop()
{
if(top == -1) printf("栈为空");
else top --;
}
void push(int x)
{
P[top++] = x;
}
bool empty()
{
if(top == - 1) return true;
return false;
}
void Top()
{
if(top != -1) printf("%d", P[top]);
else printf("空栈");
}
队列
- 队列与栈一样是一种线性结构,因此以常见的线性表如数组、链表作为底层的数据结构
队列的基本操作:
q.empty() 如果队列为空返回true,否则返回false
q.size() 返回队列中元素的个数
q.pop() 删除队列首元素但不返回其值
q.front() 返回队首元素的值,但不删除该元素
q.push() 在队尾压入新元素
q.back() 返回队列尾元素的值,但不删除该元素
q.swap() 交换两个队列的元素
数组模拟:
const int M = 100010;
// hh 表示队首,tt表示队尾
int queue[M], hh, tt;
void init()
{
hh = tt = 0;
}
void push(int x)
{
queue[tt++] = x;
}
void pop()
{
hh++;
}
bool isEmpty()
{
if(hh < tt)
return false;
return true;
}
int query()
{
return queue[hh];
}
单调栈
例题:给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1。
思路:单调栈,即使单调的,此题可以用单调递增的栈来实现,从左往右
遍历,如果栈为空输出-1,并将其放入栈内,否则判断栈顶元素是否大于当前值;那么栈顶元素就是左边最小值
参考代码:
#include<bits/stdc++.h>
using namespace std;
stack<int> p;
int main()
{
int N; cin >> N;
for(int i = 1; i <= N; ++i)
{
int x;
cin >> x;
while(!p.empty() && p.top() >= x) p.pop();
if(!p.empty() ) cout << p.top() << ' ';
else cout << -1 << ' ';
p.push(x);
}
return 0;
}
单调队列(deque)
题目:有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。您只能在窗口中看到k个数字。每次滑动窗口向右移动一个位置。
参考代码:(ps:双端队列存放的是数组下标)
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#define rep(i,n) for (int i = 1;i <= n; ++i)
#define mem(a) memset(a,0,sizeof(a))
#define ft ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define t_test int t; scanf("%d",&t);while(t--)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch&&ch<='9') x=x*10+ch-'0', ch=getchar();
return f*x;
}
const int N = 1000100;
int a[N];
deque<int> q;
int main()
{
//t_test
ft;
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; ++i) cin >> a[i];
q.clear() ;
for (int i = 1; i <= n; ++i) // min
{
while(!q.empty() && a[q.back()] > a[i]) q.pop_back() ;
q.push_back(i);
while(!q.empty() && i - k >= q.front()) q.pop_front() ;//控制窗口的大小
if(i >= k) cout << a[q.front()] << ' ';
}
cout << endl;
q.clear();
for (int i = 1; i <= n; ++i) // max;
{
while( !q.empty() && a[q.back()] < a[i]) q.pop_back();
q.push_back(i);
while( !q.empty() && i - k >= q.front()) q.pop_front();
if(i >= k) cout << a[q.front()] << ' ';
}
return 0;
}