[数据结构习题]队列——用栈实现队列

news/2024/5/20 8:33:37

[数据结构习题]队列——用栈实现队列



👉知识点导航💎:【数据结构】栈和队列

👉[王道数据结构]习题导航💎: p a g e 85.3 page85.3 page85.3

本节为栈和队列的综合练习题

在这里插入图片描述



题目描述:
在这里插入图片描述



🎇思路:双栈模拟

🔱思路分析:

由于队列是先进先出的,而栈先进后出,所以需要定义两个栈来实现先进先出:先进 S 1 S1 S1 → → 后出 S 1 S1 S1 → → 后进 S 2 S2 S2 → → 先出 S 2 S2 S2


step:

算法思路:利用栈 S 1 S1 S1 S 2 S2 S2来模拟一个队列,当需要入队时,用 S 1 S1 S1来存放已入队的元素,则压入 S 1 S1 S1的栈顶;出队时,则将 S 2 S2 S2的栈顶元素出栈

在这里插入图片描述


1.实现栈的基本操作

①定义结构体 + + + 初始化

由于为顺序栈,初始化即让 S.top==-1

#define Maxsize 50

typedef struct SqStack {
	int data[Maxsize];
	int top;
}SqStack;

//1.初始化
void InitStack(SqStack& S) {
	S.top = -1;
}

②判空&判满

对于顺序栈来说,判空为:S.top==-1 ;判满为:S.top==Maxsize-1

// 2.判满
bool Stackoverflow(SqStack& S) {
	if (S.top == Maxsize-1)
		return true;
	return false;
}

// 3.判空
bool Stackempty(SqStack& S) {
	if (S.top == -1)
		return true;
	return false;
}

③入栈

压入栈时,要判断栈是否已满,再让:S.data[++S.top]=x;

// 4.入栈
bool Push(SqStack& S, int x) {
	if (Stackoverflow(S))
		return false;
	S.data[++S.top] = x;
	return true;
}

④出栈

出栈时,先判断栈是否为空,再让:x=S.data[S.top--];

// 5.出栈
bool Pop(SqStack& S, int& x) {
	if (Stackempty(S))
		return false;
	x = S.data[S.top--];
	return true;
}

2.用栈实现队列操作

1.入队算法:

x x x入队时,是对入队栈 S 1 S1 S1 进行进栈操作,会出现几种情况:

如果 S 1 S1 S1不为栈满状态,则直接将 x x x压入 S 1 S1 S1中:

在这里插入图片描述


如果 S 1 S1 S1栈满,而 S 2 S2 S2栈为空,则先将 S 1 S1 S1中的所有元素压入栈 S 2 S2 S2中,再将 x x x压入S1中:
在这里插入图片描述

相当于先将输入的内容放入输出缓存区,这时候清空了输入条,则又可以继续输入了

在这里插入图片描述


如果 S 1 S1 S1栈满,而 S 2 S2 S2栈为非空状态,则入队失败:

同时这也意味着此时 队满Stackoverflow(S1) && !Stackempty(S2)

哪也去不了!

在这里插入图片描述


入队代码实现:

// 6.入队
bool Enqueue(SqStack& S1, SqStack& S2, int x) {
	if (!Stackempty(S1)) { //如果S1不满 直接放到S1中
		Push(S1, x);
		return true;
	}
	else if (Stackoverflow(S1) && Stackempty(S2)) { //②如果S1满 而S2为空
		while (!Stackempty(S1)) { //将S1中所有元素压入S2中,再将x压入S1中
			int tmp;
			Pop(S1, tmp);
			Push(S2, tmp);
		}
		Push(S1, x);
		return true;
	}
	else if (Stackoverflow(S1) && Stackempty(S2)) { //如果S1满且S2不为空 则无法入队
		cout << "队列已满!" << endl;
		return false;
	}
}

2.出队算法:

由于从栈中取出元素是逆序的,所以必须先将 S 1 S1 S1中的所有元素依次出栈并压入 S 2 S2 S2中,在 S 2 S2 S2中进行出栈操作,而对出队栈 S 2 S2 S2的情况进行讨论:

如果 S 2 S2 S2不为栈空,则直接将 S 2 S2 S2的栈顶元素弹出:
在这里插入图片描述


如果 S 2 S2 S2为栈空,而 S 1 S1 S1不为空,则将 S 1 S1 S1中所有元素出栈并压入栈 S 2 S2 S2中,再对 S 2 S2 S2进行出栈:

在这里插入图片描述


如果 S 1 S1 S1 S 2 S2 S2均为空栈:

则出队失败,并且这也意味着此时 队空: Stackempty(S1) && Stackempty(S2)


代码实现:

// 7.出队
bool Dequeue(SqStack& S1,SqStack& S2,int &x) {
	if (!Stackempty(S2)) { //如果S2不空
		Pop(S2, x);
		return true;
	}
	else if (!Stackempty(S1) && Stackempty(S2)) { //如果S2空但S1不空
		while (!Stackempty(S1)) {
			Pop(S1, x);
			Push(S2, x);
		}
		Pop(S2, x);
		return true;
	}
	else if (Stackempty(S1) && Stackempty(S2)) {
		cout << "队列已空!" << endl;
		return false;
	}
}

3.队空&队满:

由上述可知:

  1. 队空Stackempty(S1) && Stackempty(S2)
  2. 队满Stackoverflow(S1) && !Stackempty(S2)

代码实现:

// 8.队列的判空
bool QueueEmpty(SqStack& S1, SqStack& S2) {
	if (Stackempty(S1) && Stackempty(S2))
		return true;
	return false;
}

// 9.队满的判断
bool QueueOver(SqStack& S1, SqStack& S2) {
	if (Stackoverflow(S1) && !Stackempty(S2))
		return true;
	return false;
}

完整代码实现:

#include<iostream>
#define Maxsize 50
using namespace std;

typedef struct SqStack {
	int data[Maxsize];
	int top;
}SqStack;

// 1.初始化
void InitStack(SqStack& S) {
	S.top = -1;
}

// 2.判满
bool Stackoverflow(SqStack& S) {
	if (S.top == Maxsize-1)
		return true;
	return false;
}

// 3.判空
bool Stackempty(SqStack& S) {
	if (S.top == -1)
		return true;
	return false;
}

// 4.入栈
bool Push(SqStack& S, int x) {
	if (Stackoverflow(S))
		return false;
	S.data[++S.top] = x;
	return true;
}

// 5.出栈
bool Pop(SqStack& S, int& x) {
	if (Stackempty(S))
		return false;
	x = S.data[S.top--];
	return true;
}

// 6.入队
bool Enqueue(SqStack& S1, SqStack& S2, int x) {
	if (!Stackempty(S1)) { //如果S1不满 直接放到S1中
		Push(S1, x);
		return true;
	}
	else if (Stackoverflow(S1) && Stackempty(S2)) { //②如果S1满 而S2为空
		while (!Stackempty(S1)) { //将S1中所有元素压入S2中,再将x压入S1中
			int tmp;
			Pop(S1, tmp);
			Push(S2, tmp);
		}
		Push(S1, x);
		return true;
	}
	else if (Stackoverflow(S1) && Stackempty(S2)) { //如果S1满且S2不为空 则无法入队
		cout << "队列已满!" << endl;
		return false;
	}
}

// 7.出队
bool Dequeue(SqStack& S1,SqStack& S2,int &x) {
	if (!Stackempty(S2)) { //如果S2不空
		Pop(S2, x);
		return true;
	}
	else if (!Stackempty(S1) && Stackempty(S2)) { //如果S2空但S1不空
		while (!Stackempty(S1)) {
			Pop(S1, x);
			Push(S2, x);
		}
		Pop(S2, x);
		return true;
	}
	else if (Stackempty(S1) && Stackempty(S2)) {
		cout << "队列已空!" << endl;
		return false;
	}
}

// 8.队列的判空
bool QueueEmpty(SqStack& S1, SqStack& S2) {
	if (Stackempty(S1) && Stackempty(S2))
		return true;
	return false;
}

// 9.队满的判断
bool QueueOver(SqStack& S1, SqStack& S2) {
	if (Stackoverflow(S1) && !Stackempty(S2))
		return true;
	return false;
}

int main() {
	SqStack S1;
	SqStack S2;
	InitStack(S1);
	InitStack(S2);

	//初始化队列元素
	cout<<"请输初始化队列元素:" << endl;
	int x;
	while(cin>>x){
		Push(S1, x);
		if (cin.get() == '\n')
			break;
	}

	//入队
	cout<<"向队列中添加一个元素:" << endl;
	cin >> x;
	Enqueue(S1, S2, x);

	//出队
	cout<<"请输入要出队的元素个数:" << endl;
	int n;
	cin >> n;
	cout << "出队元素依次为:" << endl;
	int a=0;
	for (int i = 0; i < n; i++) {
		if (Dequeue(S1, S2, a))
			cout << a << " ";
		else
			break;
	}cout << endl;

	system("pause");
	return 0;
}

输出结果:

在这里插入图片描述



🎇这是一道栈和链表的综合练习题,不是很难,但有利于知识点的回顾~🎇

如有错误,欢迎指正~!

在这里插入图片描述


http://www.niftyadmin.cn/n/393956.html

相关文章

Linux 实操篇-RPM 与YUM

Linux 实操篇-RPM 与YUM rpm 包的管理 介绍 rpm 用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux 分发版中。它生成具有.RPM 扩展名的文件。RPM是RedHat Package Manager&#xff08;RedHat 软件包管理工具&#xff09;的缩写&#xff0c;类似windows 的set…

INTJ型人格适合选择哪些专业?

INTJ型人格是一种理性、独立、逻辑性强的人格类型&#xff0c;他们通常在思考问题时会非常深入&#xff0c;而且对于目标的追求非常明确。 INTJ型人格的人通常在职业发展中追求自我提升和成长&#xff0c;他们善于分析问题、制定计划和实现目标&#xff0c;具有很强的自我意识…

【JUC基础】14. ThreadLocal

目录 1、前言 2、什么是ThreadLocal 3、ThreadLocal作用 4、ThradLocal基本使用 4.1、创建和初始化 4.2、存储和获取线程变量 4.3、清理和释放线程变量 4.4、小结 4.5、示例代码 5、ThreadLocal原理 5.1、set() 5.2、get() 5.3、变量清理 5.4、ThreadLocalMap 6、…

CXGRid实现拖动鼠标多选

要实现在CXGrid中拖动鼠标多选&#xff0c;您可以按住鼠标左键并拖动鼠标&#xff0c;直到选择了要选择的单元格或行。您可以在拖动过程中按住Shift键来限制选择范围。拖动选择的单元格或行时&#xff0c;您可以按住Ctrl键来添加或删除单元格或行的选择。当您完成选择时&#x…

C++并发线程 - 如何管控线程【启动/暂停/停止/恢复】

系列文章目录 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程系列 深入理解设计模式系列 超越昨天的自己 Keeps going beyond yesterdays own 线程管控 系列文章目录1、线程最基本的使用 - 简单管控2、如何将参数传递给线程3、线程归属权居然是可以转移的4、通…

华为OD机试真题 Java 实现【租车骑绿道】【2023Q1 100分】

一、题目描述 部门组织绿岛骑行团建活动&#xff0c;租用公共双人自行车骑行&#xff0c;每辆自行车最多坐两人、最大载重 M。 给出部门每个人的体重&#xff0c;请问最多需要租用多少双人自行车。 二、输入描述 第一行两个数字 m、n&#xff0c;自行车限重 m&#xff0c;代…

山区特殊场景的倾斜摄影三维模型数据出现几何坐标偏差原因,如何修正这些坐标偏差?

山区特殊场景的倾斜摄影三维模型数据出现几何坐标偏差原因&#xff0c;如何修正这些坐标偏差&#xff1f; 山区倾斜摄影三维模型数据出现几何坐标偏差的原因可能有很多&#xff0c;其中一些常见的原因包括不同地图投影系统之间的转换问题、GPS定位误差、测量设备精度问题、摄影…

Vue3 + ElementPlus实战学习——模拟简单的联系人列表管理后台

文章目录 &#x1f4cb;前言&#x1f3af;demo 介绍&#x1f3af;功能分析&#x1f9e9;数据的展示与分页功能&#x1f9e9;编辑功能&#x1f9e9;删除功能 &#x1f3af;部分代码分析&#x1f3af;完整代码&#x1f4dd;最后 &#x1f4cb;前言 这篇文章介绍一下基于 Vue3 和…