IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构】队列(Queue) -> 正文阅读

[数据结构与算法]【数据结构】队列(Queue)

目录

一.队列(Queue)

二.队列的使用

三.队列的模拟实现(单链表实现)

四.循环队列

五.双端队列(了解)


?

一.队列(Queue)

队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 后进后出的特点

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

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

二.队列的使用

在Java中,Queue是个接口,底层是通过链表实现的。

如图,队列中主要有这些方法

其实,1和2中方法的效果几乎差不多,但是我们经常使用的是方框2中的方法,某种程度上,2中的几个方法更好

方法功能
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);
        System.out.println(queue.poll());//从队头出队列,并将删除的元素返回
        Integer val = queue.peek();//获取队头元素,但不删除
        System.out.println(val);
        if (queue.isEmpty()) {
            System.out.println("队列空");
        } else {
            System.out.println(queue.size());
        }
    }

?

三.队列的模拟实现(单链表实现)

首先,我们提出一个疑问:入队采用头插法还是尾插法呢?

如果入队采用的是头插法:入队的时候就是从头入:头插法【O(1)】

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 出队的时候:删除尾节点【O(n)】

如果入队采用的是尾插法:入队的时候就是从尾入:尾插法【O(n)】?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?出队的时候:删除头节点【O(1)】

可当我们给单向链表加一个last属性以标记尾节点时,采用尾插法入队的入队和出队的时间复杂度都是O(1),而采用头插法入队的入队是O(1),出队仍是O(n) 【这是因为要删除尾节点,就得找到尾节点的前一个】?

所以,我们如果要用单链表,采用尾插法入队更好,即尾巴入队,从头出队的方法

?

但如果是双向链表,不管从哪边入队,时间复杂度都是O(1)

下面我们来看一下用单链表模拟实现队列的代码吧

public class MyLinkedList {
    class Node{
        public int val;
        public Node next;
        public Node(int val){
            this.val = val;
        }
        public Node head;
        public Node last;
        public int UsedSize;

        /**
         * 入队
         * @param val
         */
        public void offer(int val){
            Node node = new Node(val);
            if(this.head == null){
                head = node;
                last = node;
            }else{
                last.next = node;
                last = node;
            }
            this.UsedSize++;
        }

        /**
         * 出队(从头出)
         * @return
         */
        public int poll(){
            if(isEmpty()){
                throw new RuntimeException("队列为空!");
            }else{
                int val = this.head.val;
                head = head.next;
                //处理只有一个节点的情况
                if(this.head == null){
                    last = null;
                }
                this.UsedSize--;
                return val;
            }
        }

        /**
         * 出队但是不删除
         * @return
         */
        public int peek(){
            if(isEmpty()){
                throw new RuntimeException("队列为空!");
            }
            return  this.head.val;
        }

        public int size(){
            return this.UsedSize;
        }

        public boolean isEmpty(){
            return UsedSize==0 ;
        }
    }
}

?

四.循环队列

实际使用中,我们有时还会使用一种特殊的队列——循环队列

循环队列通常用数组实现

?

我们分析一下如何实现

数组下标循环的小技巧

1. 下标最后再往后(offset 小于 array.length): index = (index + offset) % array.length
?

?2. 下标最前再往前(offset 小于 array.length): index = (index + array.length - offset) % array.length

?

?如何区分空与满

  1. ?通过添加 size 属性记录(UsedSize)
  2. ?使用标记
  3. ?保留一个位置(空一个位置)

?

例题?

力扣?

?设计循环队列:具体的解析都写在注释里啦~

class MyCircularQueue {
    private int[] elem;
    private int front;//表示队头下标
    private int rear;//表示队尾下标
    /**
     * 构造方法
     * @param k k个大小
     */
    public MyCircularQueue(int k) {
        elem = new int[k+1];//由于我们需要浪费一个空间来确定是否为满,所以k要加 1
        //如果不加 1 ,就用UsedSize==length来判断满
    }

    /**
     * 入队
     * 1.判断队列是否是满的
     * 2.不满,则把当前需要的元素放到 rear下标的地方
     * @param value
     * @return
     */
    public boolean enQueue(int value) {
        if(isFull()) {
            return false;
        }
        this.elem[rear] = value;
        //this.rear++;  这是错误的,因为是一个循环队列,要考虑大小,直接加可能会导致数组越界
        this.rear = (rear+1) % elem.length;
        return true;
    }

    /**
     * 出队
     * 1.判断队列是否为空的
     * @return
     */
    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        this.front = (this.front+1) % this.elem.length;//不能直接加 1
        return true;
    }

    /**
     * 得到队头元素
     * @return
     */
    public int Front() {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }

    /**
     * 得到队尾元素
     * @return
     */
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        /*
        return elem[rear];
        这样写是错误的,由于(0-1)=-1,会越界,我们应该考虑 rear=0的情况
         */
        int index = (this.rear==0) ? (this.elem.length-1) : (this.rear-1);
        return elem[index];
    }

    /**
     * 判断当前队列是否为空
     * rear和front相遇就是空的
     * @return
     */
    public boolean isEmpty() {
        return rear == front;//rear和front相遇就是空的
    }

    /**
     * 判断当前队列是否为满
     * 浪费一个空间来表示满
     * @return
     */
    public boolean isFull() {
        if( (rear+1)%elem.length == front ){
            return true;
        }
        return false;
    }
}

五.双端队列(了解)

下面我们再来简单的介绍一下双端队列(Deque)
?双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。
?那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。
?

Deque是一个接口,使用时必须创建LinkedList的对象。

?

?

?以上是一些队列的有关知识

?

?

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 17:03:41  更:2022-06-26 17:04:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:49:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码