用队列实现栈,用栈实现队列

news2024/11/20 13:19:03

有两个地方会讨论到栈,一个是程序运行的栈空间,一个是数据结构中的栈,本文中讨论的是后者。

栈是一个先入后出,后入先出的数据结构,只能操作栈顶。栈有两个操作,push 和 pop,push 是向将数据压栈,pop 是将数据出栈。栈还有一个操作 top,这个操作可以查看栈顶的元素,不会出栈。

队列是一种先入先出,后入后出的数据结构。

 

 1 用队列实现栈

leetcode 链接:

用队列实现栈

用队列实现栈,队列先入先出以及栈先入后出的语义不能改变。关键是怎么在压栈的时候,将数据放到队列头,这就需要两个队列进行配合。

两个队列配合的方式有两种,这两种方式均可以解答这个问题:

(1)入栈的时候进行元素移动

① 两个队列,始终保持一个队列是空的,假设是队列 A,压栈的时候,将元素放入这个队列。这样最后入队的放到了队列头,所以下次出栈的时候就是第一个出队的。满足先进后出,后进先出的要求,也就是栈的语义。

② 然后将另一个队列(假设是队列 B)里边的元素都移动到这个队列中。

这样,元素都移动到了队列 A 中,队列 B 成为了空队列。下一个元素入队的时候,将元素入队到队列 B,将元素 A 中的元素移动到 B 中。以此类推。

每个元素入队的时候都做这个操作。

第一个元素 10:入队 A,B 中没有元素不需要操作

第二个元素 20:入队 B,A 中的 10 移动到 B

第 3 个元素 30: 入队 A,B 中元素移动到 A

(2)出栈的时候进行元素移动

① 压栈的时候将元素入队到有元素的这个队列里边

② 出栈的时候将元素移动到另一个队列中,同时进行判断,当队列剩余 1 个元素的时候,这个元素就是出栈的元素,不用移动到另一个队列中了。

方法 1 的主要逻辑在 push() 函数中实现;方法 2 的主要逻辑在 top() 和 pop() 函数中都要实现。

两个方法都可以通过两个队列来实现,也可以通过一个队列也是可以实现的。

1.1 入队时处理,双队列

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
      if (q_master_.empty()) {
          q_master_.push(x);
          while (!q_slave_.empty()) {
              q_master_.push(q_slave_.front());
              q_slave_.pop();
          }
      } else {
          q_slave_.push(x);
          while (!q_master_.empty()) {
              q_slave_.push(q_master_.front());
              q_master_.pop();
          }
      }
    }
    
    int pop() {
      if (!q_master_.empty()) {
          int data = q_master_.front();
          q_master_.pop();
          return data;
      } else {
          int data = q_slave_.front();
          q_slave_.pop();
          return data;
      }
    }
    
    int top() {
      if (!q_master_.empty()) {
          return q_master_.front();
      } else {
          return q_slave_.front();
      }
    }
    
    bool empty() {
      return q_master_.empty() && q_slave_.empty();
    }

private:
  std::queue<int> q_master_;
  std::queue<int> q_slave_;
};

1.2 入队时操作,单队列

关键是 push() 函数中的操作,将元素入队之后,然后将新元素之外的元素出队,再重新入队。这样保证了新入队的元素移动到了队列头的位置,下次出栈的时候直接出队就可以。

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
        q_.push(x);
        int size = q_.size();
        for (int i = 0; i < size - 1; i++) {
            q_.push(q_.front());
            q_.pop();
        }
    }
    
    int pop() {
        int data = q_.front();
        q_.pop();
        return data;
    }
    
    int top() {
        return q_.front();
    }
    
    bool empty() {
      return q_.empty();
    }

private:
  std::queue<int> q_;
};

1.3 出队时操作,双队列

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
      if (!q_master_.empty()) {
        q_master_.push(x);
      } else {
        q_slave_.push(x);
      }
    }
    
    int pop() {
      if (!q_master_.empty()) {
          int size = q_master_.size();
          for (int i = 0; i < size - 1; i++) {
            q_slave_.push(q_master_.front());
            q_master_.pop();
          }
          int data = q_master_.front();
          q_master_.pop();
          return data;
      } else {
          int size = q_slave_.size();
          for (int i = 0; i < size - 1; i++) {
            q_master_.push(q_slave_.front());
            q_slave_.pop();
          }
          int data = q_slave_.front();
          q_slave_.pop();
          return data;
      }
    }
    
    int top() {
      if (!q_master_.empty()) {
          int size = q_master_.size();
          for (int i = 0; i < size - 1; i++) {
            q_slave_.push(q_master_.front());
            q_master_.pop();
          }
          int data = q_master_.front();
          q_master_.pop();
          q_slave_.push(data);
          return data;
      } else {
          int size = q_slave_.size();
          for (int i = 0; i < size - 1; i++) {
            q_master_.push(q_slave_.front());
            q_slave_.pop();
          }
          int data = q_slave_.front();
          q_slave_.pop();
          q_master_.push(data);
          return data;
      }
    }
    
    bool empty() {
      return q_master_.empty() && q_slave_.empty();
    }

private:
  std::queue<int> q_master_;
  std::queue<int> q_slave_;
};

1.4 出队时操作,单队列

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
        q_.push(x);
    }
    
    int pop() {
      int size = q_.size();
      for (int i = 0; i < size - 1; i++) {
        q_.push(q_.front());
        q_.pop();
      }
      int data = q_.front();
      q_.pop();
      return data;
    }
    
    int top() {
      int size = q_.size();
      for (int i = 0; i < size - 1; i++) {
        q_.push(q_.front());
        q_.pop();
      }
      int data = q_.front();
      q_.pop();
      q_.push(data);
      return data;
    }
    
    bool empty() {
      return q_.empty();
    }

private:
  std::queue<int> q_;
};

2 用栈实现队列

leetcode 链接:

用栈实现队列

用栈实现队列,需要在出队的时候进行操作。在入队的时候进行操作,算法不好实现,不像队列中的元素,比如元素顺序是 E1、E2、E3、E4、E5,那么元素在移动之后还是这样的顺序,移动多次之后还是保持这样的顺序。但是对于栈来说,每移动一次就会导致顺序翻转,所以在入队的时候进行操作的算法不好实现。

使用栈实现队列,需要使用两个栈。只使用一个栈,算法也不好实现。

两个栈 A 和 B,在入队的时候只往 A 压栈,出队的时候只从 B 出栈。当 B 是空的时候,那么将 A 中所有的元素都移动到 B。

class MyQueue {
public:
    MyQueue() {

    }
    
    void push(int x) {
      s_in_.push(x);
    }
    
    int pop() {
      if (s_out_.empty()) {
          while (!s_in_.empty()) {
              s_out_.push(s_in_.top());
              s_in_.pop();
          }
      }
      int ret = s_out_.top();
      s_out_.pop();
      return ret;
    }
    
    int peek() {
      if (s_out_.empty()) {
          while (!s_in_.empty()) {
              s_out_.push(s_in_.top());
              s_in_.pop();
          }
      }
      return s_out_.top();
    }
    
    bool empty() {
      return s_out_.empty() && s_in_.empty();
    }

private:
  std::stack<int> s_in_;
  std::stack<int> s_out_;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始:手把手教你使用Python实现PDF到Excel的转换

来百 在日常工作和学习中&#xff0c;我们经常会遇到需要将PDF文件中的数据提取到Excel表格中的情况。可能是为了进行数据分析、报告生成或者其他目的。虽然手动复制粘贴是一种方法&#xff0c;但对于大量的数据来说&#xff0c;这种方式显然效率太低。幸运的是&#xff0c;Py…

ELK 日志监控平台(一)- 快速搭建

文章目录 ELK 日志监控平台&#xff08;一&#xff09;- 快速搭建1.ELK 简介2.Elasticsearch安装部署3.Logstash安装部署4.Kibana安装部署5.日志收集DEMO5.1.创建SpringBoot应用依赖导入日志配置文件 logback.xml启动类目录结构启动项目 5.2.创建Logstash配置文件5.3.重新启动L…

DNF手游攻略:角色培养与技能搭配!游戏辅助!

角色培养和技能搭配是《地下城与勇士》中提升战斗力的关键环节。每个职业都有独特的技能和发展路线&#xff0c;合理的属性加点和技能搭配可以最大化角色的潜力&#xff0c;帮助玩家在各种战斗中立于不败之地。接下来&#xff0c;我们将探讨如何有效地培养角色并搭配技能。 角色…

用Python一键生成PNG图片的PowerPoint幻灯片

在当今的商业环境中,PowerPoint演示是展示和传递信息的常用方式。然而,手动将大量图像插入到幻灯片中往往是一项乏味且耗时的工作。但是,通过Python编程,我们可以轻松自动化这个过程,节省时间和精力。 C:\pythoncode\new\folderTOppt.py 在本文中,我将介绍如何使用Python、wx…

WebGL的医学培训软件开发

开发基于WebGL的医学培训软件是一项复杂且技术性强的任务&#xff0c;需要结合医学专业知识和计算机图形学技术。以下是详细的开发流程和关键步骤。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.需求分析与定义 目标用户&#xf…

视频推拉流EasyDSS系统如何在清理缓存文件的同时不影响缓存读写?

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将无人机设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播、巡检等应用。 有用户咨询&#xff0c;视频推…

如何成为一个专业的AI产品经理?

可以找专业的老师带。 可以找专业的内容学。 可以多遇挫折并快速学习&#xff0c;屡败屡战&#xff0c;笔者本人从业AI十年有余&#xff0c;吃了不少苦&#xff0c;有过很多或成功或失败的经历。 成为一个专业的AI产品经理需要一系列专业知识和技能的积累&#xff0c;以及在…

基于python的网页自动刷新工具

1.下载webdriver https://msedgewebdriverstorage.z22.web.core.windows.net/?prefix122.0.2365.59/下载Edge的浏览器驱动 2.安装selenium pip install selenium4.11.1 3.写代码 # -*- coding: utf-8 -*- import tkinter as tk from tkinter import messagebox import thr…

Ansible实战YAML语言完成apache的部署,配置,启动全过程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f3dd;️Ansible专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年5月24日15点59分 目录 &#x1f4af;趣站推荐&#x1f4af; &#x1f38a;前言 ✨️YAML语言回顾 &#x1f386;1.编写YAML文…

华氏温度到摄氏温度的转换之旅

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、温度转换的基本概念 二、转换公式的探究 三、编程实现转换功能 1. 代码输入与类型转换…

如何将数据从一部手机传输到另一部手机[安全快速]

概括 手机之间无需使用蓝牙即可传输文件&#xff0c;配合专业的文件传输工具更高效。本文将向您介绍几种使用不同的数据传输工具快速安全地将数据从一部手机传输到另一部手机的方法&#xff0c;特别是当有大文件或大量文件时。现在&#xff0c;我们来看看。 需要在朋友或家人之…

智慧平安小区建设方案:EasyCVR视频+AI能力全面提升小区安全管理水平

随着城市化进程的加快和科技的不断发展&#xff0c;智慧平安小区建设成为了提升社区治理水平和居民安全感的重要手段。TSINGSEE青犀EasyCVR智慧平安小区平台采集汇总智慧小区各类视频资源基础数据&#xff0c;进行分级分类管理&#xff0c;并为公安、政法、大数据局、街道社区等…

Python筑基之旅-MySQL数据库(四)

目录 一、数据表操作 1、新增记录 1-1、用mysql-connector-python库 1-2、用PyMySQL库 1-3、用PeeWee库 1-4、用SQLAlchemy库 2、删除记录 2-1、用mysql-connector-python库 2-2、用PyMySQL库 2-3、用PeeWee库 2-4、用SQLAlchemy库 3、修改记录 3-1、用mysql-conn…

APP广告变现怎么实现的,背后逻辑是什么?

广告变现的实现主要基于以下几个关键步骤和逻辑&#xff1a; 用户获取与留存&#xff1a;首先&#xff0c;APP需要吸引足够的用户并确保他们的留存率。只有拥有庞大且活跃的用户基础&#xff0c;APP才能吸引广告商投放广告。因此&#xff0c;开发者需要通过优化APP质量、提升用…

经常碰到的20个等待事件

经常碰到的20个等待事件 oracle等待事件简介 DBA团队维护的部分应用运行在oracle数据库平台&#xff0c;为及时了解数据库的运行情况&#xff0c;需要建立涵盖各个维度的监控体系&#xff0c;包括实例状态、空间使用率、ORA错误等数十项监控指标。这其中有一个有效判断数据库…

低代码开发:拖拽式可视化构建工业物联网系统

什么是低代码&#xff1f; 低代码(Low Code)是一种可视化的软件开发方法&#xff0c;通过最少的手动编码可以更快地交付应用程序。低代码平台的图形用户界面和拖放功能可自动执行开发过程的各个方面&#xff0c;从而消除对传统计算机编程方法的依赖。 什么是低代码平台&#…

关于手机中Camera Sensor Flicker产生原因和解决方法

Camera flicker相信在一部分中低端机里可以看到的现象(拍灯最为明显)。 在了解Camera flicker前&#xff0c;先了解一些词汇。 快门&#xff1a;快门是照相机用来控制感光片有效曝光时间的机构。是照相机的一个重要组成部分&#xff0c;它的结构、形式及功能是衡量照相机档次…

HarmonyOS 鸿蒙应用开发 DevEco Studio环境搭建 (值得收藏哦)

目录 1、华为开发者官网下载 DevEco Studio 2、安装DevEco Studi 3、安装过程具体步骤 4、认证华为开发者账号 5、编写第一个鸿蒙应用 1、华为开发者官网下载 DevEco Studio 前往&#xff1a;华为开发者官网地址 下载&#xff0c;我这里下载的 deveco-studio-3.1.0.500版…

如何为 kNN 搜索选择最佳 k 和 num_candidates

作者&#xff1a;Madhusudhan Konda 如何选择最好的 k 和 num_candidates&#xff1f; 向量搜索在当前的生成式人工智能/机器学习领域中已经成为一个改变游戏规则的技术。它允许我们基于语义含义而不仅仅是精确的关键词匹配来找到相似的项目。 Elasticsearch的 k-近邻&#x…

Pandas 创建层次化索引

1.创建多层次索引 1.1 隐式构造 最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组 # 导入pandasimport numpy as npimport pandas as pd​data np.random.randint(0,100,size(6,6))​# 行索引index [ ["1班","1班","1班&qu…