数据结构与算法——队列

news2024/9/27 2:45:16

概述

  计算机科学中,queue 是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据。添加的一端称为,移除的一端称为

功能

  •   插入offer(value : E) : boolean
  •   取值并移除poll() : E
  •   取值peek() : E
  •   判断是否为空isEmpty() : boolean
  •   判断队列是否满isfull() : boolean

接口代码

public interface Queue<E> {

    /**
     * 向队列尾插入值
     * @param value 待插入值
     * @return 插入成功返回 true, 插入失败返回 false
     */
    boolean offer(E value);

    /**
     * 从对列头获取值, 并移除
     * @return 如果队列非空返回对头值, 否则返回 null
     */
    E poll();

    /**
     * 从对列头获取值, 不移除
     * @return 如果队列非空返回对头值, 否则返回 null
     */
    E peek();

    /**
     * 检查队列是否为空
     * @return 空返回 true, 否则返回 false
     */
    boolean isEmpty();

    /**
     * 检查队列是否已满
     * @return 满返回 true, 否则返回 false
     */
    boolean isFull();
}

链表实现

  利用单向环形带哨兵链表实现

代码

import java.util.Iterator;
import java.util.StringJoiner;

/**
 * 基于单向环形链表实现
 * @param <E> 队列中元素类型
 */
public class LinkedListQueue<E>
        implements Queue<E>, Iterable<E> {

    private static class Node<E> {
        E value;
        Node<E> next;

        public Node(E value, Node<E> next) {
            this.value = value;
            this.next = next;
        }
    }

    private final Node<E> head = new Node<>(null, null);
    private Node<E> tail = head;
    int size = 0;
    private int capacity = Integer.MAX_VALUE;

    {
        tail.next = head;
    }

    public LinkedListQueue() {
    }

    public LinkedListQueue(int capacity) {
        this.capacity = capacity;
    }

    @Override
    public boolean offer(E value) {
        if (isFull()) {
            return false;
        }
        Node<E> added = new Node<>(value, head);
        tail.next = added;
        tail = added;
        size++;
        return true;
    }

    @Override
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        Node<E> first = head.next;
        head.next = first.next;
        if (first == tail) {
            tail = head;
        }
        size--;
        return first.value;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return head.next.value;
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        return size == capacity;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> p = head.next;

            @Override
            public boolean hasNext() {
                return p != head;
            }

            @Override
            public E next() {
                E value = p.value;
                p = p.next;
                return value;
            }
        };
    }

    @Override
    public String toString() {
        StringJoiner sj = new StringJoiner(",");
        for (E e : this) {
            sj.add(e.toString());
        }
        return sj.toString();
    }
}

数组实现

  利用移位与相与操作,解决超长队列问题。

代码

import java.util.Iterator;

/**
 * 仅用 head, tail 判断空满, head, tail 需要换算成索引值
 *
 * @param <E> 队列中元素类型
 */
public class ArrayQueue3<E> implements Queue<E>, Iterable<E> {

    /*
        求模运算:
        - 如果除数是 2 的 n 次方
        - 那么被除数的后 n 位即为余数 (模)
        - 求被除数的后 n 位方法: 与 2^n-1 按位与
     */

    private final E[] array;
    private int head = 0;
    private int tail = 0;

    @SuppressWarnings("all")
    public ArrayQueue3(int c) {
        // 1. 抛异常
        /*if ((capacity & capacity - 1) != 0) {
            throw new IllegalArgumentException("capacity 必须是2的幂");
        }*/
        // 2. 改成 2^n    13 -> 16   22 -> 32
        int n = (int) (Math.log10(c-1) / Math.log10(2)) + 1;
        array = (E[]) new Object[1 << n];
        /*
            2^4     = 16
            2^4.?   = 30
            2^5     = 32

              (int)log2(30) + 1
            2

            log2(x) = log10(x) / log10(2)

            1
            10      2^1
            100     2^2
            1000    2^3
         */
    }

    /*
        head = 0
        tail = 3  % 3 = 0
        capacity=3

        0   1   2
        d   b   c
     */
    @Override
    public boolean offer(E value) {
        if (isFull()) {
            return false;
        }
        array[tail & (array.length - 1)] = value;
        tail++;
        return true;
    }

    @Override
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        int idx = head & (array.length - 1);
        E value = array[idx];
        array[idx] = null; // help GC
        head++;
        return value;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return array[head & (array.length - 1)];
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        return tail - head == array.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int p = head;

            @Override
            public boolean hasNext() {
                return p != tail;
            }

            @Override
            public E next() {
                E value = array[p & (array.length - 1)];
                p++;
                return value;
            }
        };
    }  
}

补充

  队列——双端队列

力扣题目

  二叉树的层序遍历

来源

  数据结构与算法

路漫漫其修远兮,吾将上下而求索。

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

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

相关文章

Redis案例-微信抢红包

Redis案例-微信抢红包 1、业务描述 ​ 微信红包&#xff0c;一个人能发红包&#xff0c;红包的分发规则&#xff0c;红包能被几个人抢&#xff0c;超过24小时没有人领取自动退回原账户&#xff0c;红包详情页面有每个人的抢红包记录&#xff0c;包括金额大小和时间&#xff0…

统计学-R语言-7.3

文章目录 前言总体方差的检验一个总体方差的检验两个总体方差比的检验 非参数检验总体分布的检验正态性检验的图示法Shapiro-Wilk和K-S正态性检验总体位置参数的检验 练习 前言 本篇文章继续对总体方差的检验进行介绍。 总体方差的检验 一个总体方差的检验 在生产和生活的许多…

使用BootStrapBlazor组件搭建Bootstarp风格的Winform界面

项目地址https://gitee.com/zhang_jie_sc/my-blazor-winforms 1.安装Bootstrap.Blazor.Templates 模板 在power shell中输入dotnet new install Bootstrap.Blazor.Templates::7.6.1&#xff0c;安装7.6.1是因为版本8以后就要强制使用net8.0了&#xff0c;很多语法不一样&…

了解WPF控件:ToggleButton和Separator常用属性与用法(十三)

掌握WPF控件&#xff1a;熟练ToggleButton和Separator常用属性&#xff08;十三&#xff09; ToggleButton 一个按钮类UI元素&#xff0c;它的特点是拥有两种状态&#xff1a;选中&#xff08;Checked&#xff09;和未选中&#xff08;Unchecked&#xff09;。当用户单击Togg…

pve8.1 安装、创建centos7虚拟机及配置

之前创建虚拟机centos7时&#xff0c;硬盘分配太大了&#xff0c;做成模板后无法进行修改了&#xff0c;安装完pve8.1后&#xff0c;强迫症犯了重新创建一下顺便记录一下配置过程。由于目前centos7还是生产用的比较多的版本所以本次还是安装centos7.9版本。 一、下载镜像 下载…

使用 CDC MinIO 汇入端为 CockroachDB 保持持久数据

CockroachDB 数据库迅速崭露头角&#xff0c;作为一个坚韧且可扩展的分布式 SQL 数据库。它从其昆虫名字的坚持不懈中汲取灵感&#xff0c;即使面对硬件故障&#xff0c;CockroachDB 也能保证高可用性。其分布式架构横跨多个节点&#xff0c;类似于其昆虫原型的适应性。 凭借强…

dos攻击与ddos攻击的区别

①DOS攻击&#xff1a; DOS&#xff1a;中文名称是拒绝服务&#xff0c;一切能引起DOS行为的攻击都被称为dos攻击。该攻击的效果是使得计算机或网络无法提供正常的服务。常见的DOS攻击有针对计算机网络带宽和连通性的攻击。 DOS是单机于单机之间的攻击。 DOS攻击的原理&#…

JavaScript学习-原型和原型链

原型和原型链 示例代码 //创建一个Person类 class Person {constructor(name) {this.name name;}drink() {console.log(喝水);} } //创建一个Teacher类&#xff0c;继承Person class Teacher extends Person {constructor(name, subject) {super(name);this.subject subjec…

详细解读vcruntime140_1.dll修复的手段,如何快速解决vcruntime140_1.dll丢失问题

当出现“无法找到vcruntime140_1.dll”或程序“未能正常启动”时&#xff0c;这通常指示系统中缺失了一个关键文件&#xff1a;vcruntime140_1.dll。作为Visual C Redistributable组件的一部分&#xff0c;这个小文件在很多用Visual Studio编译的C程序运行时发挥着重要作用。解…

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…

P1042 [NOIP2003 普及组] 乒乓球 Java版最简单题解!

为什么说最简单&#xff0c;因为本人就是一个算法小白&#xff0c;只学过一点数据结构&#xff0c;打算备战蓝桥杯的&#xff0c;网上说备战蓝桥杯就去刷洛谷&#xff0c;早有听闻洛谷很难&#xff0c;今天一看算是真的被打醒了&#xff0c;对于小白是真的太难了。(;༎ຶД༎ຶ…

在Idea中使用git查看历史版本

idea查git历史 背景查看步骤总结 背景 有好几次同事到我电脑用idea查看git管理的历史记录&#xff0c;每次都说我的idea看不了历史版本&#xff0c;叫我到他电脑上去看&#xff0c;很晕&#xff0c;为什么,原来是我自己把显示历史文件的视图覆盖了&#xff0c;下面我们来一起学…

Python open函数

在Python编程中&#xff0c;open()函数是一个重要的文件操作函数&#xff0c;用于打开文件并进行读取、写入、追加等操作。本文将深入探讨open()函数的用法、语法、文件模式、示例代码&#xff0c;并探讨其在实际编程中的应用场景。 什么是open()函数&#xff1f; open()函数…

【阻塞队列】阻塞队列的模拟实现及在生产者和消费者模型上的应用

文章目录 &#x1f4c4;前言一. 阻塞队列初了解&#x1f346;1. 什么是阻塞队列&#xff1f;&#x1f345;2. 为什么使用阻塞队列&#xff1f;&#x1f966;3. Java标准库中阻塞队列的实现 二. 阻塞队列的模拟实现&#x1f35a;1. 实现普通队列&#x1f365;2. 实现队列的阻塞功…

Python.五.文件

1.文件读取的操作 1.文件的打开 open(name,mode,encoding) name:是要打开目标文件名的字符串&#xff0c;可以包含文件所在的具体路径 mode:设置打开文件的模式&#xff1a;只读 r 、写入 w 、追加 a encoding&#xff1a;编码格式 UTF-8 fopen("C:/test.txt"…

XSS_Labs靶场通关笔记

每一关的方法不唯一&#xff1b;可以结合源码进行分析后构造payload&#xff1b; 通关技巧&#xff08;四步&#xff09;&#xff1a; 1.输入内容看源码变化&#xff1b; 2.找到内容插入点&#xff1b; 3.测试是否有过滤&#xff1b; 4.构造payload绕过 第一关 构造paylo…

怎么获取二维码的链接?二维码转链接只需3步

怎么从二维码中提取内容呢&#xff1f;现在很多内容都会用二维码方式来存储&#xff0c;但是有些场景下二维码是无法使用的时候&#xff0c;想要查看二维码中的内容&#xff0c;就需要分解二维码成链接后使用。那么二维码分解成链接具体该怎么做呢&#xff1f;今天就将在线二维…

Hammer.js中文教程

一、什么是hammer.js hammerJS是一个开源的&#xff0c;轻量级的触屏设备javascript手势库&#xff0c;它可以在不需要依赖其他东西的情况下识别触摸&#xff0c;鼠标事件。允许同时监听多个手势、自定义识别器&#xff0c;也可以识别滑动方向。 优点&#xff1a; 为移动端网…

[已解决]504 Gateway Time-out 网关超时

文章目录 问题&#xff1a;504 Gateway Time-out 504 Gateway Time-out 网关超时思路解决 问题&#xff1a;504 Gateway Time-out 504 Gateway Time-out 网关超时 思路 网上的常规思路是修改nginx配置文件,增加请求执行时间,试过没有用 keepalive_timeout 600; fastcgi_con…

一文读懂: AIGC基本原理及应用领域

AIGC是利用人工智能技术来生成内容的一种新型技术。随着人工智能技术的不断发展&#xff0c;AIGC技术也得到了越来越广泛的应用。未来&#xff0c;AIGC技术将会对我们的生活和工作产生巨大的影响。 一、AIGC技术的基本原理 AIGC技术的基本原理是利用人工智能技术中…