首页 > 其他分享 >栈和队列

栈和队列

时间:2023-12-11 13:22:33浏览次数:25  
标签:sta 队列 top stack int void

前言

这里我们主要介绍手写栈和队列。

虽然有 STL 里的分装好的数据结构,但是因为封装好的数据结构跑得会很比较慢(比如 deque ),所以我们最好手写。

正文

普通栈

栈是一种后入先出的数据结构,它主要有三种功能:

  • 往栈里加入一个元素
  • 从栈头弹出一个元素
  • 查询栈顶端的元素。

所谓后入先出,意思是当执行 2 操作时,会优先弹出最近一个加入栈中的元素。

我们可以使用结构体手写栈,我们可以如下定义:

struct stack{
	int sta[100020];
	int top=0;
};
stack<int> s;

其中, sta[] 表示栈, top 表示长度。

以上三种操作,我们便可以通过三个成员函数进行手写:

 void push(int data){//操作 1
        sta[++top]=data;
    }//成员函数
 void pop(){//操作 2
        top--;
    }
 int gettop(){//操作 3
        return sta[top];
    }

再使用结构体将其封装,就可以实现手写栈多个栈了。

但是,以上代码仅支持栈元素是单个类型的,如果要定义 doublestringchar……类型的栈,是不是就太麻烦了。

这时候,我们便可以定义 template<typename T>,将类型设为 T ,进行如下定义方法:

template<typename T>
struct stack{
    T sta[100020];
    int top;
    void push(T data){
        sta[++top]=data;
    }
    void pop(){
        top--;
    }
    T gettop(){
        return sta[top];
    }
}
stack<int> a;
stack<double> b;
stack<string> c;
stack<char> d;
......

单调栈

例题导入

【模板】单调栈

很明显,暴力 O(n^2) 。

考虑二分,时间复杂度 O(nlogn) 。

能不能更快呢?

尝试用栈来加速这个求解过程。

假设在第 4 个位置是 5 ,在第 5 个位置有是 3 ,那么,对于位置 (1,3) 而言,位置 5 永远不是我们想求的答案。

于是我们会想,哪些数可能作为我们的答案,我们发现,可能成为我们答案的数应该是一个满足位置和高度均具有单调性的序列。

所以我们可以从右向左扫描序列,维护一个可能可以成为答案的序列。对于当前扫描到的数,我们把不可能成为答案的数从这个序列中剔除。这样,由于位置具有单调性,答案序列中位置最靠前的,也就是我们当前这个数对应的答案。最后,我们把当前的数加进可能成为答案的序列之中。

模拟以上操作即可:

/*Written by smx*/
#include<bits/stdc++.h>
using namespace std;
template<typename T>
struct stack_{
	T sta[3000005];
	int top=0;
	void push(int data){
		sta[++top]=data;
	}
	void pop(){
		top--;
	}
	T gettop(){
		return sta[top];
	}
};
stack_<int> s;//维护下标具有单调性
int n,ans;
int h[3000005],f[3000005];
int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	//ios::sync_with_stdio(false);
	//cin.tie(0);
	//cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	}
	s.push(0);
	for(int i=n;i>=1;i--){
		while(s.top&&h[i]>=h[s.gettop()]){//判断不会访问出界,且当前数大于栈内的数。注意用循环而不是if语句
			s.pop();
		}
		f[i]=s.gettop();//记录答案
		s.push(i);//新的数入队
	}
	for(int i=1;i<=n;i++){
		cout<<f[i]<<" ";
	}
	return 0;
}

普通队列

队列是一种先入先出的数据结构,先加进输出结构的元素会被先弹出。就像食堂
排队一样,先排好队的同学会先打到饭,这就是一种队列。

数组+2个指针

同理,定义如下:

template<typename T>
struct queue{
	T que[3000005];
	int head=1,tail=0;
	void push(int data){
		que[++tail] = data;
	}
	void pop(){
		head++;
	}
	int front(){
		return que[head];
	}
	int back(){
		return que[tail];
	}
	int get_size(){
		return tail-head+1;
	}
};
queue<int> s;

使用时, head 表示队首, tail 表示队尾。

循环队列

由于不断地进行 head++,数组会多出很多元素,浪费空间,我们便可以将这些空间利用起来,取模一个数,不过整场比赛一般不卡这个,即使会卡:

queue q:?????

人话:屁用没有

双端队列

类似普通的队列的定义,我们可以定义一个左右两端都可以入队列和出队列的数据结构,那么这个结构就是双端队列。

标签:sta,队列,top,stack,int,void
From: https://www.cnblogs.com/shimingxin1007/p/17894164.html

相关文章

  • 循环队列
    一、循环队列环形队列,有两个指针:头指针和尾指针。在队尾写入,移动尾指针;从队列头部读取,移动头指针。环形队列,其特殊性在于"环形",内存空间可以不断重复使用,无需频繁分配和释放内存。通常,我们用一个固定长度的数组来实现循环队列。示意图:1.初始化循环队列初始化:创建一个空的......
  • 架构核心技术之分布式消息队列
    Java全能学习+面试指南:https://javaxiaobear.cn今天我们来学习分布式消息队列,分布式消息队列的知识结构如下图。主要介绍以下内容:同步架构和异步架构的区别。异步架构的主要组成部分:消息生产者、消息消费者、分布式消息队列。异步架构的两种主要模型:点对点模型和发布订阅模型......
  • day11栈与队列
    day11栈与队列20.有效的括号1047.删除字符串中的所有相邻重复项150.逆波兰表达式求值1有效的括号给定一个只包括'(',')','{','}','[',']'的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被......
  • Leetcode刷题day9-栈.队列-栈转队列.队列转栈
    232.用栈实现队列232.用栈实现队列-力扣(LeetCode)请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:voidpush(intx) 将元素x推到队列的末尾intpop() 从队列的开头移除并返回元素intpeek() 返回队......
  • 第五章 栈与队列part01
    第五章栈与队列part01  232.用栈实现队列  基础逻辑(用于理解,直接运行的话会报错,C++STLstack定义的不太一样):注://C++STLStack的pop还不管弹数,得用top()拿 逻辑Code:classMyQueue{public:  stack<int>stack_Simulate......
  • 【JavaSE】数据结构(栈、队列、数组、链表)
    什么是数据结构?数据结构是计算机底层存储、组织数据的方式,是指数据相互之间是什么方式排列在一起的常见的数据结构栈、队列、数组、链表二叉树、二叉查找树、平衡二叉树、红黑树哈希表栈特点:先进后出队列特点:先进先出数组特点:有索引,内存连续优点:查询速度快O(1)缺点:增......
  • 基于Redis的简易延时队列
    基于Redis的简易延时队列一、背景在实际的业务场景中,经常会遇到需要延时处理的业务,比如订单超时未支付,需要取消订单,或者是用户注册后,需要在一段时间内激活账号,否则账号失效等等。这些业务场景都可以通过延时队列来实现。最近在实际业务当中就遇到了这样的一个场景,需要实现一个......
  • AMQP协议中的,消息队列RabbitMQ,ActiveMQ,Apache Kafka区别是什么?
    都是基于AMQP协议来的一种实现方式。参考chatGPT4回答请使用Markdown表格来展示RabbitMQ、ActiveMQ和ApacheKafka之间的区别:维度RabbitMQActiveMQApacheKafka语言ErlangJavaScala/Java协议AMQP、STOMP、MQTTAMQP、STOMP、OpenWire自定义协议......
  • python实现一个优先级队列
    实现一个优先级队列问题怎样实现一个按优先级排序的队列?并且在这个队列上面每次pop操作总是返回优先级最高的那个元素解决方案下面的类利用heapq模块实现了一个简单的优先级队列:importheapqclassPriorityQueue:def__init__(self):self._queue=[]s......
  • 消息传递:消息队列
    一、消息队列在上一章节消息传递:消息队列中提到PIPE和FIFO是基于字节流的,把这种字节流(没有消息边界)分隔成各个记录的任何方法都得由应用程序来实现。例如提到的一个记录的格式为一行,格式:1234/tmp/fifo.serv。另一方面,PIPE和FIFO有许多规则,制约的open的阻塞与否。当......