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

Java~数据结构(三)~栈和队列(Stack\Queue\Deque的常用方法和模拟实现一个栈和队列等)

文章目录

      • 知识框架
      • 栈(Stack)
      • 如何实现一个栈?
      • 栈(Stack)常用方法
      • 模拟实现一个栈(包括栈常用方法)
      • 单向队列(Queue)和双端队列(Deque)
      • 单向队列Queue常用方法
      • 双向队列Deque常用方法
      • 循环队列

知识框架

在这里插入图片描述

  • 栈和队列本质上都是线性表,只不过是特殊的线性表,操作收到了限制。
  • 栈是线性表只允许在一端进出,而队列是线性表只允许一端进,一端出。
  • Java中有栈的具体类Stack,而队列(Queue)只是定义了接口,所有实现了这个接口的具体类都可以当做一个队列来使用。

栈(Stack)

  • 什么是栈?栈是一种特殊的线性表。只能在表的一端进行插入和删除。可以进行数据插入和删除的一端称为栈顶。另一端称为栈底。
  • 栈中的元素遵循“先进后出”原则。(也就是后进先出,Last In First Out,所以也称为LIFO结构
  • 空栈:不含有任何元素的空表。
    在这里插入图片描述

如何实现一个栈?

  • 在Java中,实现栈有两个方法:一个是Java本身的集合类型Stack类型。另一个是借用LinkedList来间接实现栈(其实链表或者数组都可以间接实现一个栈的功能,LinkedList就是链表,下面会用数组模拟实现一个栈)。
  • Stack集合类型继承于Vector,由于Vector是通过数组实现的,所以Stack集合类型也是通过数组来实现的。
    在这里插入图片描述
  • 注意:我们平时所说的栈,是一种按照先入后出的线性存储结构。这种结构不仅用Java可以写,用C++也可以写。在Java中的栈,有两种实现方式,一种是本身的集合Stack,我们平常说的也就是这种。另一种就是用别的实现类来实现这种功能,比如LinkedList。(平时的Stack就是指Stack集合类型。而不是栈这种更广泛的概念。)
  • LinkedList是双向链表,不仅仅能用来实现栈,还可以被用来实现队列或者双端队列。是一个比较“全能”的数据结构。因为LinkedList实现了List接口,所以可以进行队列的操作,还实现了Deque接口,所及还能当做双端队列使用。

栈(Stack)常用方法

在这里插入图片描述
常用方法使用:

使用1public static void main(String[] args) {

        Stack<Integer> stack=new Stack<>();

        //入栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);

        System.out.println("栈中有效元素个数:"+stack.size());
        System.out.println("获取栈顶元素"+stack.peek());//获取栈顶元素,但是不弹出。
        stack.pop();//出栈,元素4出栈,栈中剩余元素3,2,1
        System.out.println("获取栈中的元素:"+stack.pop());
        System.out.println("栈中有效元素个数:"+stack.size());//获取栈的长度
        System.out.println("stack是否为空:"+stack.isEmpty());//判断栈是否为空
    }

在这里插入图片描述

模拟实现一个栈(包括栈常用方法)

class MyStack{
    private int[] arr;

    //size记录数组中元素个数
    private int size;

    public MyStack(){
        this(12);//调用无参构造,默认最大容量12
    }
    public MyStack(int MaxSize){
        this.arr=new int[MaxSize];
    }

    //入栈
    public int push(int value){
        if(this.size == arr.length){
            //栈满 需要扩容

            int[] copyArr;
            //复制数组arr,数组扩充一倍
            copyArr=Arrays.copyOf(arr,2*arr.length);
            arr=copyArr;
        }

        //将元素添加到size位置
        this.arr[size]=value;
        //元素个数+1;
        this.size++;
        //返回添加元素
        return value;
    }

    //出栈
    public int pop(){
        if(this.size == 0){
            //没有元素
            //抛出时运行异常,此处也可以自定义异常。
            throw new RuntimeException("栈中没有元素,不能出栈..");
        }
        //获得栈顶元素
        int value=this.arr[size-1];
        //size-1之后,下一次插入时会覆盖原数据,利用覆盖替代删除。
        this.size--;
        return value;
    }
    //获取栈顶元素(peek)
    public int peek(){
        if(this.size == 0){
            //没有元素
            //抛出时运行异常,此处也可以自定义异常。
            throw new RuntimeException("栈中没有元素,不能出栈..");
        }
        return this.arr[this.size - 1];
    }
    //获取元素个数
    public int getSize(){
        return this.size;
    }
    //判断栈是否为空
    public boolean isEmpty(){
        return this.size==0;
    }
    
}

单向队列(Queue)和双端队列(Deque)

  • 什么是队列?只允许在一端进行插入数据,在另一端进行删除数据的特殊线性表。进行插入操作的一端是队尾。进行删除操作的一端是队头。
  • 队列具有先进先出的特性。
    在这里插入图片描述
  • 详细图:

在这里插入图片描述

  • Java中有单向队列(Queue)和双向队列(Deque),Queue是个接口,实现了队列的基础方法。Deque是在继承Queue的基础上,增加了反向队列的方法,也包括栈的基础方法。
    在这里插入图片描述
    在这里插入图片描述
  • (上图)Java中虽然有Queue接口,但是Java并没有给出具体的实现类(栈是直接给出了Stack实现类),而是让LinkedList实现了Queue接口,所以一般用LinkedList来实现链表。

单向队列Queue常用方法

在这里插入图片描述

  • 注意:Queue中插入和删除都有两个方法可以实现,当我们使用队列时,通常采用offer添加元素和poll删除元素。不适用add与remove方法。

使用:

public static void main(String[] args) {
        Queue<Integer> q = new LinkedList<>();
        //插入元素
        q.offer(1);
        q.offer(2);
        q.offer(3);
        q.offer(4);
        q.offer(5);

        System.out.println("元素个数 : "+q.size()); // 获取元素个数 输出5

        System.out.println("获取队头元素 : "+q.peek()); // 获取队头元素,但不删除元素
        q.poll();
        System.out.println("出队列元素 : "+q.poll()); // 从队头出队列,并将删除的元素返回

        if(q.isEmpty()){
            System.out.println("队列空");
        }else{
            System.out.println("元素个数 : "+q.size());
        }
    }

双向队列Deque常用方法

在这里插入图片描述

循环队列

  • 实际使用时,可能还会接触到循环队列,循环队列一般用数组实现。就是首尾相连。
  • 使用循环队列可以解决用数组实现队列时的空间浪费问题。

在这里插入图片描述

  • 代码实现:
public class MyCircularQueue {

    private final int[] elem;
    private int front;      //队头下标
    private int rear;       //队尾下标
    private int size;

    public MyCircularQueue() {
        elem = new int[24];
    }

    //入队列
    public void offer(int val){
        if(size == elem.length){
            //可扩容,此处不实现
            throw new RuntimeException("队列已满...");
        }
        elem[rear] = val;
        //如果rear到达数组长度,则置0
        if(rear + 1 >= elem.length){
            rear = 0;
        }else {
            rear++;
        }
        size++;
    }

    public int poll(){
        if(size == 0){
            throw new RuntimeException("队列为空...");
        }
        int val = elem[front];
        if(front + 1 >= elem.length){
            front = 0;
        }else {
            front++;
        }
        size--;
        return val;
    }

    //判断元素个数
    public int size(){
        return size;
    }

    //获取队首元素
    public int peek(){
        if(size == 0){
            throw new RuntimeException("队列为空...");
        }
        return elem[front];
    }

    // 判断是否为空
    public boolean isEmpty(){
        return size == 0;
    }
}

相关文章:

  • 股票API下单接口是怎样传入交易数据的?
  • 【C++初阶】C++入门篇(二)
  • 点云LAS格式分析
  • 关于我的家乡html网页设计完整版,10个以家乡为主题的网页设计与实现
  • 有营养的算法笔记(二)
  • 10.5 - 每日一题 - 408
  • 递归、分治算法刷题笔记
  • 微服务架构秘籍:SpringCloud+SpringCloud Alibaba,全网疯传
  • HDLbits exercises 10(LATCHES AND FLIP-FLOPS后半部分题)
  • MySQL经典练习题+解题思路(四)
  • 大三开学,百度面试感受
  • 【图神经网络实战】深入浅出地学习图神经网络GNN(上)
  • 国庆旅游3天,Python 把我的疲倦治愈了
  • 数据结构与算法——算法和算法分析
  • Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo
  • 自己简单写的 事件订阅机制
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 2017年终总结、随想
  • bearychat的java client
  • Linux中的硬链接与软链接
  • Mysql5.6主从复制
  • passportjs 源码分析
  • Python - 闭包Closure
  • Twitter赢在开放,三年创造奇迹
  • Vim Clutch | 面向脚踏板编程……
  • 阿里云前端周刊 - 第 26 期
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 蓝海存储开关机注意事项总结
  • 力扣(LeetCode)22
  • 深度学习中的信息论知识详解
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 回归生活:清理微信公众号
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​水经微图Web1.5.0版即将上线
  • #FPGA(基础知识)
  • #控制台大学课堂点名问题_课堂随机点名
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (差分)胡桃爱原石
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (简单) HDU 2612 Find a way,BFS。
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (四)图像的%2线性拉伸
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • /usr/bin/env: node: No such file or directory
  • :=
  • ??myeclipse+tomcat
  • @Repository 注解
  • [autojs]逍遥模拟器和vscode对接
  • [C语言][C++][时间复杂度详解分析]二分查找——杨氏矩阵查找数字详解!!!
  • [hdu4622 Reincarnation]后缀数组
  • [LeetCode][面试算法]逻辑闭环的二分查找代码思路