我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java栈与队列超详细分析讲解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java栈与队列超详细分析讲解

一、栈(Stack)

1、什么是栈?

栈其实就是一种数据结构 - 先进后出(先入栈的数据后出来,最先入栈的数据会被压入栈底)

在这里插入图片描述

什么是java虚拟机栈?

java虚拟机栈只是JVM当中的一块内存,该内存一般用来存放 例如:局部变量当调用函数时,我们会为函数开辟一块内存,叫做 栈帧,在 java虚拟机栈中开辟,具体如下。

在这里插入图片描述

常见考点:不可能的出栈顺序

在这里插入图片描述

这道题该怎么分析呢?

首先我们知道,出栈时拿到的第一个元素为4,那么4必须入栈,因为入栈的顺序是 1 2 3 4 5 6,所以4要入栈,1 2 3 得先入栈。(通过后面分析得知,该出栈序列正确)

在这里插入图片描述

2、栈的常见方法

方法作用
E push(E item)放入元素
E pop()获取栈顶元素并弹出
E peek()获取栈顶元素
boolean isEmpty()判断栈是否为空(父类Vector的方法)

3、自己实现一个栈(底层用一个数组实现)

public class MyStack {
    public int[] elem;
    public int usedSize;

    public MyStack() {
        this.elem = new int[4];
    }

    // 放入元素
    public void push(int val) {
        if(isFull()) {
            // 如果放满了,二倍扩容
            this.elem = Arrays.copyOf(elem,2 * elem.length);
        }
        this.elem[this.usedSize++] = val;
    }
    // 获取栈顶元素并弹出
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空!");
        }
        usedSize--;
        return elem[usedSize];
    }
    // 获取栈顶元素
    public int peek() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空!");
        }
        return elem[usedSize-1];
    }
    // 是否为空
    public boolean isEmpty() {
        return usedSize == 0;
    }
    // 是否满了
    public boolean isFull() {
        return elem.length == usedSize;
    }
}

二、队列(Queue)

1、什么是队列?

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 - 先进先出。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

在这里插入图片描述

在这里插入图片描述

2、队列的常见方法

在这里插入图片描述

在这里插入图片描述

// 普通队列
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);// 队尾入
int top = queue.peek();// 获取队头元素
queue.poll();// 弹出队尾元素并返回

// 双端队列
Deque<Integer> deque = new LinkedList<>();
deque.offer(1);// 默认队尾入
deque.offerFirst(2);// 队头入
deque.offerLast(3);// 队尾入

deque.peekFirst();// 获取队头元素
deque.peekLast();// 获取队尾元素

deque.pollFirst();// 弹出队头元素并返回
deque.pollLast();// 弹出队尾元素并返回

3、队列的实现(单链表实现)

在这里插入图片描述


class Node{
    public int val;
    public Node next;

    public Node(int val) {
        this.val = val;
    }
}
public class MyQueue {
    public Node head;
    public Node tail;

    
    public void offer(int val) {
        Node node = new Node(val);
        if (head == null) {
            head = node;
            tail = node;
        }else {
            tail.next = node;
            tail = tail.next;
        }
    }

    
    public int poll() {
        if(isEmpty()) {
            throw new RuntimeException("队列为空!");
        }
        int val = head.val;
        head = head.next;
        return val;
    }

    
    public int peek() {
        if(isEmpty()) {
            throw new RuntimeException("队列为空!");
        }
        return head.val;
    }
    
    // 队列是否为空
    public boolean isEmpty() {
        return head == null;
    }
}

4、循环队列

当考虑用数组来实现一个队列, 很容易想到以下结构:

在这里插入图片描述

当我们连续从该队头中弹出元素时,就可以发现问题了

在这里插入图片描述

可以看到此时数组并没有满,但是当我们再次插入元素时,队尾却插入不了了,这时候我们可以想到将该数组看成是循环的数组,结构如下。

在这里插入图片描述

可以看出,当 front 和 rear 相遇时,队列可能的情况有两种,要么为空,要么是满的状态。那么队列什么时候为空,什么时候是满的呢?

我们有两种方法:

1、设置usedSize 当usedSize和数组长度相等时为满,等于0 则为空。

2、设置标志位 设 flag = true,每放一个元素,将 flag 置为 false,每有一个元素出队列,则将 flag 置为 true。当 front 和 rear 相遇时,flag为 true 则是空的,反之则是满的。

public class MyCircularQueue {
    public int[] elem;
    public int front;// 队头下标
    public int rear;// 队尾下标
    boolean flag = true;// 是否为空

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

    // 向循环队列插入一个元素。如果成功插入则返回真。
    public boolean enQueue(int value) {
        if (isFull()) {
            return false;
//            throw new RuntimeException("队列已满!");
        }
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        flag = false;
        return true;
    }

    // 从循环队列中删除一个元素。如果成功删除则返回真。
    public boolean deQueue() {
        if (isEmpty()) {
            return false;
//            throw new RuntimeException("队列为空!");
        }
        front = (front + 1) % elem.length;
        flag = true;
        return true;
    }

    // 从队首获取元素。如果队列为空,返回 -1 。
    public int Front() {
        if (isEmpty()) {
            return -1;
//            throw new RuntimeException("队列为空!");
        }
        return elem[front];
    }
    // 获取队尾元素。如果队列为空,返回 -1 。
    public int Rear() {
        if (isEmpty()) {
            return -1;
//            throw new RuntimeException("队列为空!");
        }
        // 如果是0下标,拿最后一个元素
        if (rear == 0) {
            return elem[elem.length-1];
        }else {
            return elem[rear - 1];
        }
    }

    // 检查循环队列是否为空。
    public boolean isEmpty() {
        if (rear == front && flag){
            return true;
        }
        return false;
    }
    // 检查循环队列是否已满。
    public boolean isFull() {
        if (rear == front && !flag){
            return true;
        }
        return false;
    }
}

到此这篇关于Java 栈与队列超详细分析讲解的文章就介绍到这了,更多相关Java 栈与队列内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java栈与队列超详细分析讲解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python队列Queue超详细讲解

Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递,本文给大家讲解Python队列Queue的相关知识,需要的朋友参考下吧
2023-05-16

GoLangRabbitMQTTL与死信队列以及延迟队列详细讲解

这篇文章主要介绍了GoLangRabbitMQTTL与死信队列以及延迟队列,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2022-12-15

怎么分析Java数据结构中的栈与队列

今天就跟大家聊聊有关怎么分析Java数据结构中的栈与队列,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一,栈1,概念在我们软件应用 ,栈这种后进先出数据结构的应用是非常普遍的。比如你
2023-06-29

Java@GlobalLock注解详细分析讲解

这篇文章主要介绍了Java@GlobalLock注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2022-11-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录