数据结构——栈与队列

本文详细介绍了数据结构中的栈和队列的基本概念、实现方式以及在数组中的模拟操作。进一步探讨了单调栈解决找左边最小值的问题,以及单调队列在滑动窗口最大值/最小值问题中的应用。通过实例代码展示了如何利用C++实现这些数据结构和算法,帮助读者深入理解它们的工作原理。
摘要由CSDN通过智能技术生成

  • 栈是一种操作受限的线性表只允许从一端插入和删除数据。

栈的实现(1):

STL中的stack:

  1. 定义:stack<数据类型> P(变量名);
  2. 插入x: P.push(x);
  3. 返回栈顶元素:P.top();
  4. 删除栈顶元素:P.pop();
  5. 判断栈是否为空:P.empty(),为空返回1
  6. 栈的大小: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W⁡angduoyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值