【408DS算法题】基础005-用两个栈实现队列

题目

用两个栈来实现一个队列, 使用n个元素来完成n次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。保证操作合法,即pop操作执行使队列不为空。

要求: 时间复杂度 O ( n 2 ) O(n^2) O(n2), 空间复杂度 O ( n ) O(n) O(n)


分析实现

通俗来讲栈和队列都是一种操作受限的线性表,通过这种操作上的限制封装好的数据结构,可以安全又便捷地完成一些特定的任务和实现更高级的算法。
二者具体限制如下:

  • 栈(Stack):只能从一侧入栈(push),从同一侧出栈(pop)(多个元素连续入栈时,先进后出)
  • 队列(Queue):只能从一侧入队,从另一侧出队(多个元素连续入栈时,先进先出)
    在这里插入图片描述

从上图可以直观地看出——对于栈,入栈顺序与出栈顺序为逆序(先进后出);而对于队列,入栈顺序与出栈顺序为原序(先进先出)。

类比负负得正这样的思路,出队操作时可将所有stack1内元素出栈先加入到stack2中,然后对stack2进行出栈,这样得到的元素就是原序了。
在这里插入图片描述

#include <iostream>
#include <stack>
using namespace std;
stack<int> stack1;
stack<int> stack2;

void enqueue(int x){
	// 入队时元素暂存于stack1中
	stack1.push(x);
}
void dequeue(){
	// 出队时分两种情况 (题中保证出队时队列不为空, 故不再考虑异常情况)
	// 1. stack2不为空, 直接出栈
	if (!stack2.empty()){
		int t = stack2.top();
		stack2.pop();
		cout << "出队元素为: " << t << endl;
		return;
	}
	// 2. stack2为空, 将stack1中元素全部转移到stack2中, 再出栈
	while (!stack1.empty()){
		int t = stack1.top();
		stack1.pop();
		stack2.push(t);
	}
	int t = stack2.top();
	stack2.pop();
	cout << "出队元素为: " << t << endl;
}


总结

本题从实现角度看,实用性不大(好好的栈为什么要转成队列啊 x_x)。

但通过本题可以更好地理解栈和队列的性质,此外本题所用到的思想还是比较有用的——两次序列反转得到正序序列(类似与用数组逆置实现数组循环左移的思路,明天会介绍一下)。

另附测试所用主函数:

int main(){
	while (1){
		cout << "请输入要执行操作(1.入队 2.出队 3.退出): ";
		int op;
		cin >> op;
		if (op == 1){
			cout << "请输入入队元素: ";
			int t;
			cin >> t;
			// 执行push操作
			enqueue(t);
		}
		else if (op == 2){
			// 执行pop操作
			dequeue();
		}
		else if (op == 3){
			cout<<"程序结束"<<endl;
			break;
		}
		else{
			cout << "输入错误, 请重新输入: ";
		}
	}
	return 0;
}

再附栈和队列的应用举例:
栈:后缀表达式的计算、记录函数调用信息
队列:用户请求时的CPU分配

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值