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

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



一、队列的概念

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

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

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

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;
}

二、队列的接口

代码如下:

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++,代码如下:

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--。代码如下:

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值,代码如下:

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,代码如下:

public int size() {
        return usedSize;
    }

执行效果如下:

返回队列元素的个数。

(5)isEmpty方法

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

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

执行效果如下:

判断队列是否为空。


四、最终代码

//自定义接口
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);
    }
}

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

相关文章
|
2月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
160 77
|
11天前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
26 11
|
1月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
92 29
|
25天前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
1月前
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
106 25
|
2月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
54 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
2月前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
52 9
|
2月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
48 7
|
2月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
80 5
|
3月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充