栈和队列(数据结构)

news2024/12/24 20:31:39

1. (Stack)

1.1 概念
:一种特殊的线性表,其 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO Last In First Out )的原则。
压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶
出栈:栈的删除操作叫做出栈。 出数据在栈顶
如图所示:
进栈:进栈顺序是ABCD,A先压入栈底,B压在A上,如此依次压栈,最后的D就是栈顶数据
出栈:只能从一端出,所以栈顶数据先出,出栈顺序就为DCBA,D最先出,A最后出

 现实生活也有很多像栈一样的结构,如枪里的子弹最先打出去的是最后装的子弹,羽毛球桶最先拿出来的羽毛球是最后放进去的,都符合栈的后进先出LIFO(Last In First Out)的原则。

1.2栈的常用方法

2. 队列(Queue)

2.1 概念
队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为 队尾( Tail/Rear 出队列:进行删除操作的一端称为 队头 Head/Front

2.2 队列的实现

如图我们可以知道队列是一个接口,接口不能实例化,但可以通过实现了该接口的类来实例化,所以   Queue可以通过ArrayList,LinkedList,PriorityQueue等来实例化该接口;

public static void main ( String [] args ) {
Queue < Integer > q = new LinkedList <> ();
Queue < Integer > q1 = new ArrayList <> ();
Queue < Integer > q2  = new  PriorityQueue <> ();
}

 循环队列

如何区分空与满
1. 通过添加 size 属性记录
2. 保留一个位置
3. 使用标记
通过1方法来模拟实现k长度的循环队列:
class MyCircularQueue {
    int[] elem;
    int front;
    int rear;
    int size;
    public MyCircularQueue(int k) {
        elem=new int[k];
        front=rear=0;
    }
    
   public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }else{
            elem[rear]=value;
            rear=(rear+1)% elem.length;
            size++;
            return true;
        }

    }
    
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }else{
            front=(front+1)%elem.length;
            size--;
            return true;
        }
    }
    
    public int Front() {
        if(isEmpty()){
            return -1;
         }
        return elem[front];
    }
    
    public int Rear() {
         if(isEmpty()){
            return -1;
         }
         int rear1=(rear==0)?elem.length-1:rear-1;//rear==0的时候比较特殊
        return elem[rear1];
    }
    
    public boolean isEmpty() {
        return size==0;
    }
    
    public boolean isFull() {
        return size==elem.length;
    }
}

通过2方法来模拟实现k长度的循环队列:
class MyCircularQueue {
    int[] elem;
    int front;
    int rear;
    public MyCircularQueue(int k) {
        elem=new int[k+1];//浪费一个空间来判断循环队列的队满;
        front=rear=0;
    }
    
   public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }else{
            elem[rear]=value;
            rear=(rear+1)% elem.length;
            return true;
        }

    }
    
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }else{
            front=(front+1)%elem.length;
            return true;
        }
    }
    
    public int Front() {
        if(isEmpty()){
            return -1;
         }
        return elem[front];
    }
    
    public int Rear() {
         if(isEmpty()){
            return -1;
         }
         int rear1=(rear==0)?elem.length-1:rear-1;//rear==0的时候比较特殊
        return elem[rear1];
    }
    
    public boolean isEmpty() {
        return front==rear;
    }
    
    public boolean isFull() {
        return (rear+1)% elem.length==front;
    }
}

4.栈和队列的相互转化

4.1用队列实现栈

栈:先进后出

队列:先进先出

进栈的实现:两队列都空就放数据到队列1里,否则就哪个队列为空就放哪里

出栈的实现:将有不为空的队列里的size-1个元素方到另一个队列里,然后就将只剩下一个元素的队列出队列就实现的出栈;

class MyStack {

    Queue<Integer> queue1;

    Queue<Integer> queue2;

    public MyStack() {

        queue1=new LinkedList<>();

        queue2=new LinkedList<>();

    }

    public void push(int x) {

        if(!queue1.isEmpty()){

            queue1.add(x);

        }else if(!queue2.isEmpty()){

            queue2.add(x );

        }else{

            queue1.add(x);

        }

    }

    public int pop() {

        if(empty()){

            return -1;

        }

        if (queue1.isEmpty()){

            int size= queue2.size();

            for (int i = 0; i < size-1; i++) {

                int val=queue2.poll();

                queue1.add(val);

            }

            return queue2.poll();

        }

        else {

            int size= queue1.size();

            for (int i = 0; i < size-1; i++) {

                int val = queue1.poll();

                queue2.add(val);

            }

            return queue1.poll();

        }

    }

    public int top() {

        if(empty()){

            return -1;

        }

        if (queue1.isEmpty()){

            int size= queue2.size();

            for (int i = 0; i < size-1; i++) {

                int val=queue2.poll();

                queue1.add(val);

            }

            int val2= queue2.peek();

            queue1.add(queue2.poll());

            return val2;

        }

        else {

            int size= queue1.size();

            for (int i = 0; i < size-1; i++) {

                int val = queue1.poll();

                queue2.add(val);

            }

            int val2= queue1.peek();

            queue2.add(queue1.poll());

            return val2;

        }

    }

    public boolean empty() {

        return (queue2.isEmpty()&&queue1.isEmpty());

    }

}

注意: 

问题:观察上图发现只是实例化queue接口的类不一样,其余代码一样,那为什么结果会不一样呢?

解答:

优先级队列 是会自动按照升序排序的 也就是每次push进来一个元素 都会自动排成升序  所以stack中从栈底到栈顶分别是  1 2 2 3 4,因此结果是4  4  3


而双向链表是没有排序这个性质 从栈底到栈顶分别是  1 2 3 4 2 ,因此结果是 2 2 4 

4.1用栈实现栈队列

栈:先进后出

队列:先进先出

进队的模拟实现:

stack1专门用来放元素,都为空的时候就将元素加入stack1中,stack1不为空就直接push,为空就将stack2中的元素全部放入stack1中

出队的模拟实现:

stack2专门用来出元素,进行出对操作时将元素放入stack2中出元素即可

class MyQueue {

    Stack<Integer> stack1;

    Stack<Integer> stack2;

    public MyQueue() {

        stack1=new Stack<>();

        stack2=new Stack<>();

    }

    public void push(int x) {

        if(!stack1.isEmpty()) {

            stack1.push(x);

        }else if(!stack2.isEmpty()){

            int size=stack2.size();

            for (int i = 0; i < size; i++) {

                 int val=stack2.pop();

                 stack1.push(val);

            }

            stack1.push(x);

        }else{

            stack1.push(x);

        }

    }

    public int pop() {

        if(empty()){

            return -1;

        }

        if(stack2.isEmpty()){

            int size=stack1.size();

            for (int i = 0; i < size; i++) {

                stack2.push(stack1.pop());

            }

            return stack2.pop();

        }else{

            return stack2.pop();

        }

    }

    public int peek() {

        if(empty()){

            return -1;

        }

        if(stack2.isEmpty()){

            int size=stack1.size();

            for (int i = 0; i < size; i++) {

                stack2.push(stack1.pop());

            }

            return stack2.peek();

        }else{

            return stack2.peek();

        }

    }

    public boolean empty() {

        return stack1.isEmpty()&&stack2.isEmpty();

    }

}

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

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

相关文章

Profinet 转 4路 MODBUS 网关

一、功能概述 1.1 设备简介 本产品是 Profinet 和 Modbus RTU 网关&#xff0c;使用数据映射方式工作。 本产品在Profinet侧作为Profinet从站&#xff0c;接西门子PLC 如 1200、1500、200Smart 等&#xff1b;在 Modbus RTU 侧做为 RTU 主站或从站&#xff0c;接 ModbusRTU …

FLUX.1 实测,堪比 Midjourney 的开源 AI 绘画模型,无需本地显卡,带你免费实战

要列举 AI 绘画开源界的几个关键贡献&#xff0c;一定少不了 Stable Diffusion。 还记否前不久刚推出的 Stable Diffusion 3&#xff1f; 其背后的团队 Stability AI&#xff0c;真的是一波三折&#xff0c;其核心成员出走&#xff0c;成立了一个新公司&#xff1a;Black For…

抖店飞鸽客服自动回复软件开发教程与下载体验(.NET版)

转载请注明出处&#xff01; 原文链接&#xff1a;https://blog.csdn.net/zgyulongfei/article/details/140960430 本文适合的读者为&#xff1a; 抖店&#xff08;抖音小店&#xff09;个体商家&#xff1b;抖店店群商家&#xff08;店群商家&#xff1a;指的是开了几十个抖…

如何用python实现将中缀表达式改成后缀表达式

例&#xff1a;如何将1 *(3 * 4 /(8 - (7 0)))改成后缀表达式 可以先看看这篇文章&#xff0c;写得很详细清楚 思路 从左到右依次遍历中缀表达式各个字符 第一个字符为运算数&#xff0c;直接输出&#xff1a; 第二个字符为操作符&#xff0c;满足 栈空/优先级高于栈顶操…

[Vue篇]vue3组合式API实现todo列表

今天的例子是使用vue3的一个新 API&#xff1a;computed()。它可以让我们创建一个计算属性 ref&#xff0c;这个 ref 会动态地根据其他响应式数据源来计算其 .value。计算属性会自动跟踪其计算中所使用的到的其他响应式状态&#xff0c;并将它们收集为自己的依赖。计算结果会被…

Typora 伪装 LaTeX 中文样式主题 学习笔记

最近发现一个比较有意思的项目&#xff0c;Typora 伪装 LaTeX 中文样式主题 用来写毕设论文的初稿&#xff0c;格式可以统一控制&#xff0c;比较方便。项目“第五章”源格式是“5 系统测试”靠左&#xff0c;就像5.1一样。搜索了一下获得了一些零散的知识点记下来。 在Typora的…

leetCode- - - 链表

目录 1.反转链表&#xff08;leetcode206&#xff09; ​编辑 2. 链表内指定区间反转&#xff08;leetcode92&#xff09; 3.链表中的节点每k个一组翻转&#xff08;leetcode25&#xff09; 4.合并两个排序的链表&#xff08;leetcode21&#xff09; 5.链表的中间节点&am…

揭开 OKR 神秘面纱:打破OKR的概念 –(第1部分)

请注意&#xff0c;《 OKR 解密 》分为5个部分&#xff0c;您目前正在学习其中的一个基本部分&#xff08;5个部分中的第1部分&#xff09;。在这5个要素中&#xff0c;我们将从理论&#xff08;第1部分&#xff09;、应用&#xff08;第2部分&#xff09;、最佳实践&#xff0…

机房托管费用贵吗?机房托管要考虑哪些因素?

机房托管费用受多种因素影响&#xff0c;包括地理位置、设备规模、服务水平、安全性要求等。不同配置和服务质量的托管价格差异较大&#xff0c;一般1U服务器托管费用一年在2000到5000元之间。Rak部落为您整理发布机房托管费用的差异&#xff0c;希望对您选择机房托管时有帮助。…

【GD32 MCU入门教程】四、GD32 MCU 常见外设介绍(3)NVIC 介绍

NVIC(Nested vectored interrupt controller&#xff0c;嵌套向量中断控制器)是Cortex-M处理器的一部分&#xff0c;它是可编程的&#xff0c;且寄存器位于存储器映射的系统控制空间(SCS)。NVIC与内核相辅相成&#xff0c;共同完成对中断的响应。本章将介绍中断的优先级设置、如…

教育机构如何避免数据泄露?两种方法保护数据安全

随着数字化时代的发展&#xff0c;教育机构的很多信息都以数字化的方式存储在计算机或移动存储设备中。为了避免数据泄露&#xff0c;我们需要加密保护重要数据。下面我们就来了解一下教育机构避免数据泄露的方法。 超级加密3000 电脑在教育行业中扮演着重要的角色&#xff0c…

阿里云万网推出首个域名AI大模型智能体应用,上线“.ai”等40个全新域名后缀

中国域名保有量3160万&#xff0c;以9.4%的份额位居全球第二。 域名资源越来越紧张&#xff0c;运维越来越复杂&#xff0c;面对的网络攻击也越来越频繁&#xff0c;都给这一领域提出了更大挑战。 8月8日&#xff0c;在阿里云万网焕新发布会上&#xff0c;阿里云宣布域名产品服…

waf绕过:网络安全狗绕过

引言&#xff1a; 所有的绕过原理都大致一致&#xff0c;但是并不是所有的绕过都能起到作用&#xff0c;渗透测试主要还是一个猜加试的过程&#xff0c;本文仅供参考 网络攻击或扫描绕过 1.get绕过&#xff08;未开启cc防护&#xff09; 网络安全狗的默认防护为&#xff0c;拒…

【C++】模拟实现reverse_iterator(反向迭代器适配器)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 &#x1f4cc;什么是适配器 &#x1f4cc;了解reverse_iterator官方标准 &#x1f4cc;了解模拟实现reverse_iterator 二.逐步实现项目功能模块及…

【C++综合项目】——基于Boost库的搜索引擎(手把手讲解,小白一看就会!!)

目录 一、前言 二、项目的相关背景 ⚡什么是Boost库&#xff1f;⚡ ⚡什么是搜索引擎&#xff1f;⚡ ⚡为什么要做Boost搜索引擎&#xff1f;⚡ 二、搜索引擎的宏观原理 三、搜索引擎技术栈和项目环境 四、正排索引 VS 倒排索引 —— 搜索引擎的具体原理 &#x…

leetcode22. 括号生成,DFS深度优先搜索

leetcode22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 示例 2&am…

SQL面试题练习 —— 最后一次登录停留时长

目录 1 题目2 建表语句3 题解 题目来源&#xff1a;腾讯微信。 1 题目 有一张用户登录日志表ods_usr_login_log, 包含user_id&#xff08;用户id&#xff09;、ds&#xff08;登录时间&#xff09;以及stay_time&#xff08;停留时长&#xff0c;单位:ms&#xff09; 问题&…

再等等,iPhone 17系列大革新,即将带来颠覆性的升级

自从苹果在2021年的iPhone 13 Pro系列中引入了ProMotion自适应刷新率技术以来&#xff0c;这项技术便成为了高端智能手机显示技术的重要标志。 如今&#xff0c;随着iPhone 17系列即将登场&#xff0c;我们有望见证这项技术向下一代更广泛的设备拓展。不仅如此&#xff0c;iPh…

每日一题~ abc 365 E 异或运算(拆位+贡献)

处理位运算常用的方法&#xff1a; 拆位法&#xff08;一位一位的处理&#xff0c;通常题目中会给出元素的最大是2的的多少次幂&#xff0c;当然也有给10的次幂的&#xff0c;自己注意一下就可以了&#xff09; 常用的思想 &#xff1a; 算贡献。 异或的性质&#xff1a; A^A0 …

抖音外卖区域服务商有哪些城市开放了?搭建本地生活系统抢先入局的成功率如何?

随着多家互联网大厂对本地生活重视程度的不断提高&#xff0c;本地生活服务商逐渐成为众多创业者心目中的首选赛道。在此背景下&#xff0c;抖音外卖区域服务商的申请通道一经开放便引发了一阵申请热潮。 毕竟&#xff0c;根据艾瑞咨询数据预测&#xff0c;到2025年&#xff0…