算法基础-数据结构:栈和队列

栈的特点

先进后出,和一个半封闭容器类似,放了一堆肉饼,先放的肉饼后倒出来

stk[n]数组代表栈,tt代表栈点

关于栈的插入

void add(int x)//插入元素
{
	stk[++t] = x;
}

关于栈的删除

void del( )//删除元素,即弹出一个肉饼
{
	tt--;
}

关于判断栈是否为空

bool stkempty()//判断栈是否为空
{
	if (tt > 0) return false;
	else return true;
}

总实现代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>

using namespace std;

const int N = 10010;

int stk[N], tt;//stk表示栈,tt表示栈点下标

void add(int x)//插入元素
{
	stk[++t] = x;
}

void del( )//删除元素,即弹出一个肉饼
{
	tt--;
}

bool stkempty()//判断栈是否为空
{
	if (tt > 0) return false;
	else return true;
}
//栈顶 stk[tt]
int main()
{
	return 0;
}

例题

问题描述

有一序列,输出每个数左边第一个比他小的数,没有则输出-1

诀窍:在while循环判断条件时,只要想该数不符合条件则跳过即可

//找出每个数左边离它最近的比它大/小的数
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstdio>
using namespace std;

const int N = 10010;

int stk[N], tt;


//暴力法
//void vio(int n)
//{
//	for (int i = 0;i < n;;++i)//对每个数的列举
//	{
//		int j = 0;
//		for (j = i -1;j >= 0;--j)
//		{
//			if (stk[i] > stk[j])
//			{
//				cout << stk[j]<<' ';
//				break;
//			}
//		}
//		if (j == -1) cout << -1 << ' ';
//	}
//}

int main()
{
	int n;
	scanf("%d ", &n);

	//单调栈法
	for (int i = 0;i < n;++i)
	{
		int x;
		scanf("%d ", &x);
		while (tt && stk[tt] >= x) tt--;
		if (tt) printf("%d\n", stk[tt]);
		else printf("-1\n");

		stk[++tt] = x;
	}

}

队列

队列的特点

先进先出,和枪上膛相似,先插进去的子弹先打出来

q[N]表示队列,hh表示对头,tt表示队尾

关于队列的插入

void add(int x)//队尾插入元素
{
	q[++tt] = x;
}

关于队列的删除(弹出)

void del( )//在队头弹出元素
{
	hh++;
}

关于队列的判断是否为空

bool qempty()//判断是否为空
{
	if (hh <= tt) return false;
	else return true;
}

总实现代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>

using namespace std;

const int N = 10010;

int q[N], hh, tt = -1;//hh表示队头,tt表示队尾 

void add(int x)//队尾插入元素
{
	q[++tt] = x;
}
void del( )//在对头弹出元素
{
	hh++;
}

bool qempty()//判断是否为空
{
	if (hh <= tt) return false;
	else return true;
}

//对头元素q[hh],队尾元素q[tt]
int main()
{
	return 0;
}

例题

//求出一定序列中,滑动窗口里的最小值和最大值
//第一行输出最小值
//第二行输出最大值 
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>

using namespace std;

const int N = 1000010;

int a[N],q[N],hh,tt;

int main()
{
	int n,k;
	scanf("%d %d", &n,&k);

	hh = 0, tt = -1;
	for (int i = 0;i < n;++i) scanf("%d", &a[i]);

	for (int i = 0;i < n;++i)
	{
		//判断队头是否滑出窗口
		if (hh <= tt && i - k + 1 > q[hh]) hh++;
		//出队
		while (hh <= tt && a[q[tt]] >= a[i]) tt--;//只要队尾比他大
		//就跳出队列,因为之后的滑动窗口都不会选择这个队尾作为输出结果
		q[++tt] = i;//下标入队,从队尾入
        //放在输出前的原因是
		//队列可能一个不剩,那么的数就是最小值
		if (i >= k - 1) printf("%d ", a[q[hh]]);
		
	}
	cout << endl;
	hh = 0, tt = -1;
	for (int i = 0;i < n;++i)
	{
		//判断队头是否滑出窗口
		if (hh <= tt && i - k + 1 > q[hh]) hh++;
		//出队
		while (hh <= tt && a[q[tt]] <= a[i]) tt--;//只要队尾比他大
		//就跳出队列,因为之后的滑动窗口都不会选择这个队尾作为输出结果
		q[++tt] = i;//下标入队,从队尾入
		if (i >= k - 1) printf("%d ", a[q[hh]]);
	}

	cout << endl;

	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

涅槃豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值