数据结构 模拟实现Queue队列(双链表模拟)

目录

一、队列的概念

二、队列的接口

三、队列的方法实现

(1)offer方法

(2)poll方法

(3)peek方法

(4)size方法

(5)isEmpty方法

四、最终代码


一、队列的概念

类似我们现实生活中的在食堂排队打饭,排队靠前的先打饭,他为什么排队靠前呢,就是因为他先进行排队,名次靠前,才轮到他打饭,如图:

而队列是先进先出的数据结构,先放进去队列里的元素先出来,和栈的先进后出不同,类似上面的食堂排队打饭的例子。

我们自定义一个MyQueue类,里面有双向链表ListNode类,链表里面有存放数据的val变量,next域和prev域,记录头结点的head和尾节点的last,还有记录链表元素个数的usedSize,代码如下:

java 复制代码
public class MyQueue implements IQueue{
    class ListNode {
        public int value;
        public ListNode prev;
        public ListNode next;
        public ListNode(int value) {
            this.value = value;
        }
    }
    ListNode head;
    ListNode last;
    int usedSize;
}

二、队列的接口

代码如下:

java 复制代码
public interface IQueue {
    public boolean offer(int x);
    public int poll();
    public int peek();
    public int size();
    public boolean isEmpty();
}

三、队列的方法实现

(1)offer方法

此方法是入队列方法,首先要创建一个链表node,判断链表中为不为空,如果是空,就把head和last定义成node,usedSize++;如果不为空,就要尾差,把last.next变成node,node.prev变成last,最后再把last = node,usedSize++,代码如下:

java 复制代码
    public boolean offer(int x) {
        ListNode node = new ListNode(x);
        if(head == null) {
            head = node;
            last = node;
        } else {
            last.next = node;
            node.prev = last;
            last = last.next;
        }
        usedSize++;
        return true;
    }

执行效果如下:

队列个数usedSize = 2,链表有两个节点。

(2)poll方法

此方法是出队列方法,首先判断链表是不是空,如果是空就出不了队列,抛异常;如果不为空,就判断head.next为不为空,也就是判断队列是不是只有一个元素,如果只有一个元素,就取出头结点的val值,再把head和last置为空,usedSize--;如果有多个元素,就取出头结点的val值,把头结点的next置为空,头结点往后走一步,头结点的prev置空,usedSize--。代码如下:

java 复制代码
    public int poll() {
        if(head == null) {
            //队列为空,出不了队列,抛异常
            throw new EmptyException("队列为空");
        }
        if(head.next == null) {
            int retValue = head.value;
            last = null;
            head = null;
            usedSize--;
            return retValue;
        }
        int retValue = head.value;
        ListNode nodeNext = this.head.next;
        head.next = null;
        nodeNext.prev = null;
        head = nodeNext;
        usedSize--;
        return retValue;
    }

//自定义异常类
public class EmptyException extends RuntimeException{
    public EmptyException(String msg) {
        super(msg);
    }
}

执行效果如下:

出队列三次,把队列出完,如果里面没元素了,就会抛异常。

(3)peek方法

此方法是取出队列的首元素,但不删除。首先要判断队列是不是空的,是空的就抛异常,不为空就返回队首元素val值,代码如下:

java 复制代码
    public int peek() {
        if(head == null) {
            //队列为空,出不了队列,抛异常
            throw new EmptyException("队列为空");
        } else {
            int retValue = head.value;
            return retValue;
        }
    }

//自定义异常类
public class EmptyException extends RuntimeException{
    public EmptyException(String msg) {
        super(msg);
    }
}

执行效果如下:

只拿队列首元素,不出队列。

(4)size方法

直接返回usedSize,代码如下:

java 复制代码
    public int size() {
        return usedSize;
    }

执行效果如下:

返回队列元素的个数。

(5)isEmpty方法

直接返回head == null,代码如下:

java 复制代码
    public boolean isEmpty() {
        return this.head == null;
    }

执行效果如下:

判断队列是否为空。


四、最终代码

java 复制代码
//自定义接口
public interface IQueue {
    public boolean offer(int x);
    public int poll();
    public int peek();
    public int size();
    public boolean isEmpty();
}

//MyQueue类
public class MyQueue implements IQueue{
    class ListNode {
        public int value;
        public ListNode prev;
        public ListNode next;
        public ListNode(int value) {
            this.value = value;
        }
    }
    ListNode head;
    ListNode last;
    int usedSize;

    @Override
    public boolean offer(int x) {
        ListNode node = new ListNode(x);
        if(head == null) {
            head = node;
            last = node;
        } else {
            last.next = node;
            node.prev = last;
            last = last.next;
        }
        usedSize++;
        return true;
    }

    @Override
    public int poll() {
        if(head == null) {
            //队列为空,出不了队列,抛异常
            throw new EmptyException("队列为空");
        }
        if(head.next == null) {
            int retValue = head.value;
            last = null;
            head = null;
            usedSize--;
            return retValue;
        }
        int retValue = head.value;
        ListNode nodeNext = this.head.next;
        head.next = null;
        nodeNext.prev = null;
        head = nodeNext;
        usedSize--;
        return retValue;
    }

    @Override
    public int peek() {
        if(head == null) {
            //队列为空,出不了队列,抛异常
            throw new EmptyException("队列为空");
        } else {
            int retValue = head.value;
            return retValue;
        }
    }

    @Override
    public int size() {
        return usedSize;
    }

    @Override
    public boolean isEmpty() {
        return this.head == null;
    }
}

//自定义异常类
public class EmptyException extends RuntimeException{
    public EmptyException(String msg) {
        super(msg);
    }
}

都看到这了,点个赞再走吧,谢谢谢谢谢!

相关推荐
CSharp精选营2 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假5 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠6 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦13 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠14 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾14 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres82114 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q14 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒14 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记14 天前
单项不带头不循环链表
数据结构·链表