栈和队列基础

目录

一.队列简述

二.栈

三.例题


一.队列简述

队列多用于辅助,很少有单独的题目。例如图的BFS,需要队列辅助实现。

常见运用:

单调队列:概念和单调栈类似。应用很少,多用于对一些算法的优化(动态规划等)不再赘述。

优先队列:普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。

优先队列具有最高级先出的特征。基于堆(大顶堆/小顶堆)实现。

编程中多使用C++容器:

#include

priority_queue pq;//大顶堆

priority_queue, greater > p;//小顶堆

二.栈

在数据结构中,我们已经详细了解了栈的基础知识,特点是先进后出,这里主要通过例题的方式来加深对栈的理解和运用,一般使用c++  stl库中的stack。

三.例题

(1)P4387 【深基15.习9】验证栈序列 - 洛谷

题目大意:给出一个入栈的序列,再给出一个出栈的序列,然后判断出栈的序列是否合法,合法输出Yes,不合法输出No。(这里定义stack s)

思路:通过模拟栈的出栈入栈来判断是否合法。具体步骤为:用i代指入栈序列a[i],j代指出栈序列b[j],初始都指向1, 首先入栈第一个元素,然后再判断s.top()是否和b[j]相等,如果相等则出栈,j++,直到s.top()和b[j]不相等为止,不相等则继续入栈。循环上述操作,最后判断栈是否为空,为空输出Yes,不为空则输出No。

参考代码:

//验证栈序列
#include
#include
#include
using namespace std;
const int N=100010;
int a[N],b[N];
stack s;
int main()
{
	int n;
	cin>>n;
	
	while(n--)
	{
		int x;
		cin>>x;
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		//每一次的操作之前都要清空数据,初始化栈 
		while(!s.empty())  {s.pop();} 
	
		
		for(int i=1;i<=x;i++) scanf("%d",&a[i]);
		for(int i=1;i<=x;i++) scanf("%d",&b[i]);
		
		int j=1;
		for(int i=1;i<=x;i++)
		{
			s.push(a[i]);
			while(!s.empty()&&s.top()==b[j])
			{
				s.pop();
				j++;
			}
		}
		
		if(s.empty()) printf("Yes\n");
		else printf("No\n");
		
	}
 } 

(2)735. 小行星碰撞 - 力扣(LeetCode)

题目大意:定义一行小行星,每个小行星的数组元素的绝对值代表每个小行星的重量,如果是正数则是向右运动,负数则是向左运动,如果会发生碰撞,绝对值更大的会把绝对值更小的行星撞碎,绝对值相同则都被消灭,给定一个数组,输出最终留下的小行星的序列。

思路:这道题是经典的括符匹配的变式题,行星的运动有以下四种情况(假设往右为+,往左为-):  +  + 不撞   - -  不撞  + - 会撞  - + 不撞 

即概括为:

以下情况不会发生碰撞,可把当前行星压入栈

            1.栈为空,不管当前行星是正是负(往左还是往右)都要压入栈;

            2.当前行星和栈顶行星同号说明同向移动不会碰撞;

            3.当前行星往右移动,栈顶行星向左移动也不会碰撞;

只有一种情况会发生碰撞,需要出栈:当前行星往左,栈顶行星往右,做判断:

            1.栈顶元素大于abs(当前元素),当前元素被撞毁,栈顶不变;

            2.栈顶元素等于abs(当前元素),栈顶弹出和当前元素抵消;

            3.栈顶元素小于abs(当前元素),栈顶弹出,并与新栈顶继续完成上述判断;

最终返回栈即可。

注意:因为最后要输出序列,栈不能进行该操作,所以我们使用vector容器模拟栈。

(3)参考代码:

//小行星碰撞
#include
#include
using namespace std;
vector asteroidCollision(vector& asteroids) {
    int n=asteroids.size();
    vector res;
    
    for(int i=0;i0)
	    {
	    	res.push_back(asteroids[i]);
		}
	  else
	  {
	  	while(res.size()>0&&res.back()<-asteroids[i]&&res.back()>0)
	  	{
	  		res.pop_back();
		  }
		if(res.size()>0&&res.back()==-asteroids[i])
		{
			res.pop_back();
		}
		else
		{
			if(res.empty()||res.back()<0)
			{
				res.push_back(asteroids[i]);
			}
		}
	  }	
	}
return res;
    
 }
int main()
{
	int n;
	cin>>n;
	vector s;
	
	for(int i=0;i>x;
		s.push_back(x);
	}
	
	vector ans=asteroidCollision(s);
	for(int i=0;i

你可能感兴趣的:(算法)