当前位置: 首页 > news >正文

栈和队列的相互实现

文章目录

  • 一、用栈实现队列
      • 入队:
      • 出队:
    • Java代码实现:
  • 二、用队列实现栈
      • 入栈:
      • 出栈:
    • Java代码实现:
  • 附:C++版代码
    • 1、用栈实现队列
    • 2、用队列实现栈

栈(stack):先进后出,后进先出。限定在表尾进行插入删除的线性表。

队列(queue):先进先出,后进后出。限定在表头删除,在表尾插入的线性表。

那么如何用栈来实现队列和如何用队列来实现栈的数据结构呢?

一、用栈实现队列

单个栈肯定无法实现队列,所以至少应该用两个栈来实现队列。

入队:

  • 数据栈:每次有新元素来时,先把存放的元素弹入辅助栈,再把新元素压入数据栈底;
  • 辅助栈:等待新元素进入数据栈以后依次弹出元素压入数据栈中;

根据这两个栈的功能,不管是数据栈中是否有元素存在,新元素都会被沉到栈底中,实现入队的功能。

出队:

由于在入队时,通过数据栈与辅助栈的交换,实现了后加入的元素沉在栈底,先进入的元素保留在栈顶,直接通过出栈弹出即可

Java代码实现:

public class StackImplQueue {// 数据栈private Stack<Integer> stack;// 辅助栈private Stack<Integer> aux;StackImplQueue() {stack = new Stack<>();aux = new Stack<>();}// 入队--通过数据栈与辅助栈相互交换,保证新加入的元素沉在数据栈底public void enqueue(Integer e) {while (!stack.isEmpty()) {aux.push(stack.pop());}stack.push(e);while(!aux.isEmpty()){stack.push(aux.pop());}}// 出队--弹出数据栈元素public Integer dequeue(){return stack.pop();}// 查看队头元素public Integer peek(){return stack.peek();}// 是否为空public boolean isEmpty(){return stack.isEmpty();}public static void main(String[] args) {StackImplQueue queue = new StackImplQueue();queue.enqueue(1);System.out.println(queue.peek());queue.enqueue(2);System.out.println(queue.peek());queue.enqueue(3);System.out.println(queue.peek());System.out.println("=============");System.out.println(queue.dequeue());System.out.println(queue.dequeue());System.out.println(queue.dequeue());}
}

二、用队列实现栈

入栈:

入栈的元素要在队头,而队列入队的元素在队尾,只需让队头至队尾前的其它所有元素依次出队再入队,直至在队尾新加入的元素被移到队头,也即实现了让新压入的元素保留在栈顶

出栈:

由于在入栈时保证队列中新加入队尾的元素被移到了队头,出栈只需弹出队头元素即可

Java代码实现:

public class QueueImplStack {// 定义队列private Queue<Integer> queue;public QueueImplStack() {queue = new LinkedList();}// 入栈--在队尾加入元素后,让其他元素按顺序出队再入队,保持新加入的元素永远在队头public void push(Integer e) {queue.offer(e);int size = queue.size();int i = 0;while (i < size - 1) {queue.offer(queue.poll());i++;}}// 出栈--将队尾前的其它所有元素出队再入队,直至队尾元素移到队头public Integer pop() {return queue.poll();}// 查看栈顶元素--即队头元素public Integer peek() {return queue.peek();}// 是否为空public boolean isEmpty() {return queue.isEmpty();}public static void main(String[] args) {QueueImplStack stack = new QueueImplStack();stack.push(1);System.out.println(stack.peek());stack.push(2);System.out.println(stack.peek());stack.push(3);System.out.println(stack.peek());System.out.println("=============");System.out.println(stack.pop());System.out.println(stack.pop());System.out.println(stack.pop());System.out.println(stack.isEmpty());}
}

附:C++版代码

1、用栈实现队列

#include<stack>
#include<iostream>using namespace std;class queue{
public:stack<int> dataStack;//数据栈 stack<int> auxStack;//辅助栈//入队,通过辅助栈让新元素沉于栈底
void push(int x) {while(!dataStack.empty()){auxStack.push(dataStack.top());dataStack.pop();}dataStack.push(x);while(!auxStack.empty()){dataStack.push(auxStack.top());auxStack.pop();}
}// 出队--弹出数据栈元素int outqueue(){int temp = dataStack.top();dataStack.pop();return temp;}// 查看队头元素int top(){return dataStack.top();}// 是否为空bool empty(){return dataStack.empty();}};int main(){queue iq;iq.push(1);cout<<iq.top()<<endl;iq.push(2);cout<<iq.top()<<endl;iq.push(3);cout<<iq.top()<<endl;cout<<"-------------"<<endl;cout<<iq.outqueue()<<endl;cout<<iq.outqueue()<<endl;cout<<iq.outqueue()<<endl;	return 0;
}

2、用队列实现栈


#include<deque>
#include<iostream>using namespace std;class stack{
public:deque<int> de;// 入栈--在队尾加入元素后,让其他元素按顺序出队再入队,保持新加入的元素永远在队头void push(int x) {de.push_front(x);int size = de.size();int i = 0;while (i < size - 1) {de.push_front(de.back());de.pop_back();i++;}}// 出栈--将队尾前的其它所有元素出队再入队,直至队尾元素移到队头int pop() {int temp = de.front();de.pop_front();return temp;}// 查看栈顶元素--即队头元素int top() {return de.front();}// 是否为空bool isEmpty() {return de.empty();}			
};int main(){stack iq;iq.push(1);cout<<iq.top()<<endl;iq.push(2);cout<<iq.top()<<endl;iq.push(3);cout<<iq.top()<<endl;cout<<"-------------"<<endl;cout<<iq.pop()<<endl;cout<<iq.pop()<<endl;cout<<iq.pop()<<endl;	return 0;
}

本文参考来源:

  • 用队列实现栈,用栈实现队列,听起来有点绕,都搞懂了就掌握了精髓! - 云+社区 - 腾讯云 (tencent.com)
  • 《小灰的算法之旅》
http://www.lryc.cn/news/37368.html

相关文章:

  • iTab新标签页重磅更新 |这些功能绝对有你想要的新体验!
  • 【改机教程】iOS系统去除小黑条,改拍照声、拨号音、键盘音,不用越狱,支持所有机型
  • Android10开机向导中复用设置中的Wifi界面
  • 川农机械专业小伙转行Java开发,年薪20w
  • 华为OD机试题 - 打印文件(JavaScript)| 机考必刷
  • 免费常用API大全,程序员必备
  • MySQL主从复制,读写分离
  • 什么是UEFI签名认证?UEFI签名有什么好处?
  • 案例14-课程推送页面逻辑整理--vue
  • 5大GPU厂商共建 | openKylin社区GPU SIG首次例会召开!
  • SpringBoot读取配置文件
  • 51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信
  • C++友元
  • MySQL内置函数
  • mysql数据库之innodb存储引擎架构之内存架构
  • Vue:(三十五)路由vue-router
  • Dynabook笔记本电脑无法开机怎么重装新系统?
  • React Native基础知识点
  • nginx 平滑升级
  • 数据结构——链表OJ题目讲解(2)
  • GitHub上线重量级分布式事务笔记,再也不怕面试官问分布式了
  • C++语法规则1(C++面向对象 )
  • Web漏洞-CSRF漏洞
  • Python3-面向对象
  • 拐点!新能源车交付均价首次「低于」燃油车,智能电动成新爆点
  • JavaScript String 字符串对象实例合集
  • 实习生培养计划
  • 【服务器管理】Wordpress服务器内存占用太高(优化方案详解)
  • 【ECCV 2022】76小时动捕,最大规模数字人多模态数据集开源
  • 联合解决方案 | 亚信科技AntDB数据库携手浪潮K1 Power赋能关键行业数字化转型,助力新基建