不良人系列-复兴数据结构(栈和队列)

 个人主页:爱编程的小新☆ 

不良人经典语录:“相呴相济 玉汝于成 勿念 心安”

目录

一. 栈(stack)

1. 栈的概念

2. 栈的常见方法

3.栈的模拟实现

 ​编辑

二. 队列

1. 队列的概念

2. 队列的使用

 2.1 队列的常见方法

2.2 队列的模拟实现

 2.3 队列的分类

(1) 普通队列

(2) 循环队列 

 (3) 双端队列

 三. 栈和队列的优缺点

1. 栈的优缺点

 2. 队列的优缺点


一. 栈(stack)

栈是一种重要的数据结构,接下来我们来看看什么是栈

1. 栈的概念

栈是一种只能在一端进行插入和删除操作的特殊线性表,进行数据操作的一端称作栈顶,那么在另一端则称为栈底,它采用后进先出的原则存储数据,即最后插入的数据最先被取出。

栈的基本操作:

  • 入栈/压栈/进栈(push):将新的元素插入到栈顶
  • 出栈(pop):删除栈顶元素并返回其的值
  • 查看栈顶元素(peek):返回栈顶元素但是不删除它
  • 判断栈是否为空:(isEmpty):若栈为空返回true,否则返回false
  • 获取栈的大小(size):返回栈中元素的个数

 栈在生活中的例子:

比如我们的羽毛球桶,后放进的球会先被取出(统一往球头的方向出); 

2. 栈的常见方法

方法功能
Stack()

构造一个空的栈

E push(E  e)将e放入栈,并返回e
E pop()将栈顶元素出栈并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()检测栈是否为空
public static void main(String[] args) {
        Stack<Integer> stack=new Stack<>();
        //将元素放入栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        System.out.println(stack);//1,2,3,4,5
        System.out.println(stack.size());//栈中有效元素个数:5
        System.out.println(stack.peek());//栈顶元素:5
        stack.pop();//5出栈
        System.out.println(stack.isEmpty());//判断栈是否为空:false
    }

3.栈的模拟实现

从下图可以看见,Stack其实是继承了Vector,Vector和ArrayList类似都是基于数组实现的容器并且是动态的顺序表,但是不同的是:Vector是线程安全的数据结构

 

 线程安全和不安全的概念:

在多线程编程中,线程安全和线程不安全是两个重要的概念(这里了解一下即可)

  • 线程安全:指的是一段代码或者一个数据结构在多线程环境中被多个线程同时访问或者操作时,还是能够正确的运行,不会出现数据不一致、错误结果、程序崩溃等问题
  • 线程不安全:指的是一段代码或者一个数据结构在多线程环境中被多个线程同时访问或者操作时,可能出现数据竞争、数据不一致、错误结果、程序崩溃等问题,导致程序的行为不可预测。

 Stack的模拟实现:

public class Mystacks {
    public int []elem;//使用数组模拟实现栈
    public int usedsize;//有效元素的个数

    public Mystacks() {
        this.elem=new int[10];//默认栈的初始空间为10
    }
    
    public int size(){//获取栈中有效元素的个数
        return usedsize;
    }
    
    public void push(int value){//入栈
        //在入栈前我们需要判断一下栈是否满了,如果满了则需要进行扩容
        if(isFull()){
            //扩容
            this.elem= Arrays.copyOf(elem,elem.length*2);
        }
        elem[usedsize++]=value;
    }
    //该方法不对用户开放,设置为private权限即可
    private boolean isFull(){
        return usedsize==elem.length;
    }
    
    public int pop(){//删除栈顶元素,并返回
        //判断栈是否为空,为空则返回-1
        if(isEmpty()){
            return -1;
        }
        int val=elem[usedsize];
        usedsize--;
        return val;
    }
    
    public boolean isEmpty(){
        return usedsize==0;
    }
    
    public int peek(){//获取栈顶元素
        if(isEmpty()){
            throw new RuntimeException("栈为空,无法获取栈顶元素");
        }
        return elem[usedsize-1];
    }
}

 那么其实不止可以使用数组来实现栈,也可以使用链表来实现栈:

链式栈:使用链表来存储数据栈数据元素,每个节点包含数据域和指向下一个节点的指针域。其优点是可灵活扩展不存在栈溢出的问题,缺点是需要而外的指针空间,实现相对复杂

二. 队列

1. 队列的概念

队列也是一种特殊的线性表,它允许在表的一端进行插入操作,而在另一端进行删除操作,允许插入的一端称为队尾,允许删除的一端称为队头,元素按照先进先出的原则存储数据

 队列的基本操作:

  • 入队(offer):将元素添加到队尾
  • 出队(poll):从队头删除元素并返回值
  • 查看队头元素(peek):返回队头元素的值,但不改变队列的状态
  • 判断队列是否为空(isEmpty):若队列为空返回true,否则返回false
  • 获取队列大小(size):返回队列中元素的个数

 队列在生活中的例子:

就像一群小朋友在排队玩滑滑梯,先排队的人先玩滑滑梯,后排队的人后玩,遵循了我们队列的原则:先进先出,后进后出

2. 队列的使用

在Java中,Queue是一个接口,底层是通过链表来实现的,所以在实例化的时候必须实例化LinkedList的对象,因为LinkedList实现了Queue接口

 2.1 队列的常见方法

方法功能
boolean offer(E e)入队列
E poll ()出队列
peek()获取队头元素
int size()获取队列中有效元素的个数
boolean isEmpty()检测队列是否为空
 public static void main(String[] args) {
        Queue<Integer> queue=new LinkedList<>();
        //入队列
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        System.out.println(queue);//1,2,3,4,5
        System.out.println(queue.size());//5
        System.out.println(queue.peek());//5
        queue.poll();//出队列
        System.out.println(queue);//2,3,4,5
        System.out.println("判断队列是否为空:"+queue.isEmpty());
    }

2.2 队列的模拟实现

在模拟实现队列之前我们来思考一下,是采用单向链表来实现队列好还是双向链表来实现队列好?

实际上双向链表才是最优的选择:

使用单向链表:在插入新元素的时间复杂度为O(n),因为我们需要遍历链表来找到最后一个元素的位置,此时的效率是没有双向链表好的

使用双向链表:在插入新元素和删除元素的时间复杂度都为O(1),可以直接通过对头指针和队尾指针进行入队和出队的操作,效率较高

public class Myqueue {
    static class ListNode{//定义一个内部类来充当我们的节点
        public int value;
        public ListNode next;//存放下一个节点的地址
        public ListNode prev;//存放前一个节点的地址

        public ListNode(int value) {
            this.value = value;
        }
    }

    public ListNode head=null;
    public ListNode last=null;
    public int usedsize=0;

    public void offer(int val){
        //创建新的节点
        ListNode node=new ListNode(val);
        //判断队列是否为空,如果为空将新节点的地址赋值给头节点的地址
        //如果不为空,将新节点添加到队尾
        if(isEmpty()){
            head=node;//头节点是该节点
            last=node;//尾节点也是该节点
        }else{
            last.next=node;//将node的地址赋值给当前尾节点的下一个节点地址
            node.prev=last;//将当前尾节点的地址赋值给node节点的前一个节点地址
            last=node;//将尾节点指向新节点
        }
        usedsize++;//有效元素个数++
    }
    public boolean isEmpty(){//判断队列为不为空
        return usedsize==0;
    }

    public int poll(){//出队
        // 1. 队列为空
        // 2. 队列中只有一个元素----链表中只有一个节点---直接删除
        // 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除
        int val = 0;
        if(head == null){
            return -1;
        }else if(head == last){
            last = null;
            head = null;
        }else{
            val = head.value;
            head = head.next;
            head.prev = null;
        }
        --usedsize;//将有效元素--
        return val;//返回删除的值
    }
    
    public int peek(){//获取队尾元素
        if(head==null){
            return -1;
        }
        return head.value;
    }
    
    public int size(){//获取队列中有效元素的个数
        return usedsize;
    }

}

 2.3 队列的分类

(1) 普通队列

普通队列就是队列最基本的形式,我们模拟实现的就是普通队列,普通队列遵行先进先出的原则

(2) 循环队列 

循环队列是将队列存储空间的最后一个位置绕到第一个位置,从而形成一个环,依然遵循先进先出的原则进行操作:

循环队列的好处 :

  • 相较于普通队列,解决了顺序队列(底层用数组实现的队列)中可能出现的假溢出问题,提高了存储空间的利用率
  • 入队和出队的时间复杂度均为O(1),操作效率高
 (3) 双端队列
双端队列( deque)是指允许两端都可以进行入队和出队操作的队列,它综合了栈和队列的特点,元素可以从队头和队尾进行插入或删除,那么在集合框架中有一个Deque, deque “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。 Deque 是一个接口,使用时必须创建 LinkedList 的对象。

 三. 栈和队列的优缺点

1. 栈的优缺点

栈的优点:

  • 操作简单高效:入栈和出栈操作的时间复杂度均为O(1),能快速实现数据的插入和删除,在对时间要求严格的场景中表现出色。
  • 空间利用率高:只需动态分配内存来存储栈中的元素,无需预留大量额外空间,内存管理高效。

栈的缺点:

  • 数据访问受限:只能访问栈顶元素,若要访问其他元素,需先将栈顶元素依次出栈,操作不便且效率低。
  • 功能相对单一:主要用于数据的暂存和特定顺序的处理,在复杂数据结构和算法中,单独使用栈可能无法满足需求,需与其他数据结构配合。

 2. 队列的优缺点

队列的优点:

  • 先进先出顺序保证:严格按照先进先出原则处理数据,在模拟现实世界中的排队现象、任务调度等场景中,能确保数据处理的公平性和顺序性。
  • 多端操作灵活:双端队列等特殊队列结构支持在两端进行插入和删除操作,为数据处理提供了更多灵活性,可适应不同应用场景需求。

队列的缺点:

  • 出队操作效率问题:在某些实现方式中,出队操作可能涉及到元素的移动或指针的调整,时间复杂度可能较高,影响整体性能。
  • 空间管理复杂:在动态分配内存的队列中,频繁的入队和出队操作可能导致内存碎片产生,影响内存空间的有效利用和管理。

 以上就是本期栈和队列的全部内容啦,在此感谢大家的观看!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划篇】步步带你深入解答成功AC最优包含问题(通俗易懂版)

本篇小鸡汤&#xff1a;待到苦尽甘来时&#xff0c;我给你讲讲来时路。 欢迎拜访&#xff1a;羑悻的小杀马特.-CSDN博客 本篇主题&#xff1a;解答洛谷的最优包含问题 制作日期&#xff1a;2024.12.23 隶属专栏&#xff1a;C/C题海汇总 ​​ 目录 本篇简介&#xff1a; 一动态…

【大语言模型】ACL2024论文-29 答案即所需:通过回答问题实现指令跟随的文本嵌入

【大语言模型】ACL2024论文-29 答案即所需&#xff1a;通过回答问题实现指令跟随的文本嵌入 目录 文章目录 目录文章信息摘要研究背景问题与挑战如何解决创新点算法模型实验效果推荐阅读指数&#xff1a;★★★★☆ 后记 文章信息 答案即所需&#xff1a;通过回答问题实现指令…

模型的量化(Quantization)

文章目录 一、浮点数格式&#xff1a;FP64, FP32, FP16, BFLOAT16, TF32之间的相互区别1、关于浮点数2、常见的浮点数格式 二、量化&#xff08;Quantization&#xff09;1、基本概念2、量化的实现8bit量化4bit量化 三、QLora四、大语言模型量化方法对比&#xff1a;GPTQ、GGUF…

10. zynq应用开发--camke编译

使用SDK工具 如果只做 Linux 应用开发&#xff0c;只需要一个 sdk.sh 文件即可&#xff0c;可以脱离 Petalinux 和 Vitis&#xff0c;也可以编译其三方的应用&#xff0c;可以说一劳永逸。 配置根文件系统 petalinux-config -c rootfs 编译SDK petalinux-build --sdk Linux主…

CSS学习记录20

CSS 3D 转换 通过CSS transform 属性&#xff0c;您可以使用以下3D转换方法&#xff1a; rotateX()rotateY()rotateZ() rotateX() 方法 rotateX() 方法使元素绕其X轴旋转给定角度&#xff1a; #myDiv {transform: rotateX(150deg); } rotateY() 方法 rotateY() 方法使元…

开发微信小程序的过程与心得

起因 作为家长&#xff0c;我近期参与了学校的护学岗工作。在这个过程中&#xff0c;我发现需要使用水印相机来记录护学活动&#xff0c;但市面上大多数水印相机应用都要求开通会员才能使用完整功能。作为一名程序员&#xff0c;我决定利用自己的技术背景&#xff0c;开发一个…

【论文笔记】Visual Alignment Pre-training for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Alignment Pre-tra…

数据可视化echarts学习笔记

目录&#xff0c;介绍 知识储备 一端操作&#xff0c;多端联动的效果&#xff08;开启了多个网页&#xff0c;操作一端&#xff0c;多个网页的效果会跟着改变&#xff09; cmd命令控制面板返回上一级或上上级 在当前目录打开文件&#xff1a; cd 文件名 在Windows命令提示符&am…

踏踏实实练SQLday1-1连续登录

踏踏实实练SQLday1 1连续登录1.1查询连续登录3天以上的用户第一步去重第二步-开窗rownumber&#xff0c;用date减一下&#xff0c;对结果进行分组 -- over()开窗函数知识图谱第三步 1.2查询连续登录最大天数用户1.3某个用户连续登录天数注意先where一下这个用户的数据过滤出来.…

Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…

数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)

Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 第二章前言部分作者提到&#xff1a;技术的介绍应该通过涵盖各种行业的熟悉的用例展开&#xff08;赞同…

Postman接口测试02|执行接口测试、全局变量和环境变量、接口关联、动态参数、断言

目录 五、Postman 1、安装 2、postman的界面介绍 六、Postman执行接口测试 1、请求页签 3、响应页签 七、Postman的环境变量和全局变量 1、创建环境变量和全局变量可以解决的问题 2、postman中的操作 八、接口关联 1、第一种方式&#xff1a;Json提取器 2、第二种方…

Oracle 日常巡检

1. 检查服务器状态 1.1. CPU使用情况 1.1.1. top top 命令是 Linux 和 Unix 系统中用于显示实时系统状态的工具&#xff0c;特别是对于监控 CPU 和内存的使用非常有用。 在命令行中输入 top&#xff0c;top 会显示一个实时更新的界面&#xff0c;其中包含系统的关键指标&am…

计算机组成原理的学习笔记(8)-- 指令系统·其一 指令的组成以及数据寻址方式

学习笔记 前言 ​ 本文主要是对于b站尚硅谷的计算机组成原理的学习笔记&#xff0c;仅用于学习交流。 1. 指令 1.1 组成 操作码&#xff08;Opcode&#xff09;&#xff1a;指指令中执行特定操作的部分。地址码&#xff1a;指令中用于指定操作数位置的部分。 1.2 扩展操作…

JavaScript 标准内置对象——Array

1、构造函数 2、静态方法 // 从可迭代或类数组对象创建一个新的浅拷贝的数组实例 // arrayLike 想要转换成数组的类数组或可迭代对象 Array.from(arrayLike, mapFn, thisArg) Array.fromAsync(arrayLike, mapFn, thisArg) // 异步Array.isArray(value) // 判断传递的值是否是一…

IndexOf Apache Web For Liunx索引服务器部署及应用

Apache HTTP Server 是一款广泛使用的开源网页服务器软件,它支持多种协议,包括 HTTP、HTTPS、FTP 等 IndexOf 功能通常指的是在一个目录中自动生成一个索引页面的能力,这个页面会列出该目录下所有的文件和子目录。比如网上经常看到的下图展现的效果,那么接下来我们就讲一下…

【PSINS】EKF、UKF、CKF三个滤波下的组合导航(松组合)对比

该 MATLAB 代码实现了扩展卡尔曼滤波&#xff08;EKF&#xff09;、无迹卡尔曼滤波&#xff08;UKF&#xff09;和无迹卡尔曼滤波的变体&#xff08;CKF&#xff09;的对比&#xff0c;主要用于导航与定位领域&#xff0c;通过处理惯性测量单元&#xff08;IMU&#xff09;和GP…

PPT画图——如何设置导致图片为600dpi

winr&#xff0c;输入regedit打开注册表 按路径找&#xff0c;HKEY_CURRENT_USER\Software\Microsoft\Office\XX.0\PowerPoint\Options&#xff08;xx为版本号&#xff0c;16.0 or 15.0或则其他&#xff09;。名称命名&#xff1a;ExportBitmapResolution 保存即可&#xff0c;…

Linux复习4——shell与文本处理

认识vim编辑器 #基本语法格式&#xff1a; vim 文件名 •如果文件存在&#xff0c;进入编辑状态对其进行编辑 •如果文件不存在&#xff0c;创建文件并进入编辑状态 例&#xff1a; [rootlocalhosttest]# vim practice.txt #Vim 编辑器三种模式&#xff1a; 命令模式&a…

Gmsh有限元网格剖分(Python)---点、直线、平面的移动

Gmsh有限元网格剖分(Python)—点、直线、平面的移动和旋转 最近在学习有限元的网格剖分算法&#xff0c;主要还是要参考老外的开源Gmsh库进行&#xff0c;写一些博客记录下学习过程&#xff0c;方便以后回忆嘞。 Gmsh的官方英文文档可以参考&#xff1a;gmsh.pdf 但咋就说&a…