数据存储——队列(Queue)

    科技2024-06-23  72

    数据存储——队列(Queue)

    本章节的源代码位于gitee上,想要下载的请点击数据存储——队列

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

    队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

    相关的队列执行原理就如下图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZpMmwFD0-1602055132967)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201007141952158.png)]

    接下来我们就来编写一个队列。队列的编写依然采用链表的方式。该类主要编写如下几个方法。

    empty() 如果队列为空返回true,否则返回false size() 返回队列中元素的个数 pop() 删除队列首元素但不返回其值 front() 返回队首元素的值,但不删除该元素 push() 在队尾压入新元素 back() 返回队列尾元素的值,但不删除该元素

    队列的创建与添加数据

    队列的创建于栈是十分类似的,需要注意的是,栈可以采用单指针进行数据操作,而队列需要使用双指针,一个指针在队首,一个指针在队尾,队尾指针负责压入数据,队首指针负责弹出数据。

    interface IQueue<T>{ void push(T data);//压入数据 } class QueueImpl<T> implements IQueue<T>{ private Node hand;//队首 private Node next;//队尾 private int size;//队列长度 @Override public void push(T data) { Node node = new Node(data); if(this.hand==null){ this.hand = node; this.next = node; } else { this.next.last = node; this.next = this.next.last; } this.size ++ ; } private class Node<T>{//链表结点 private T data; private Node last;//保存下一个结点 private Node(T data){ this.data = data; } } }

    在队列中压入数据其实和链表是完全一样的,如果你对Java中的LinkedList类有了解的话就可以知道它也是继承了一个名为Queue的接口,该接口就是Java定义的一个队列操作接口。所以这里就不细说队列的压入数据操作了

    队列数据操作(弹出元素、队列是否为空)

    在操作队列数据的时候需要注意的是,移动的是队首的指针,队尾的指针是不需要移动的,只有在压入数据的时候才需要移动队首的指针。接下来的操作和单链表操作类似,这里就快速过一下。

    empty() 如果队列为空返回true,否则返回false size() 返回队列中元素的个数 pop() 删除队列首元素但不返回其值 front() 返回队首元素的值,但不删除该元素 back() 返回队列尾元素的值,但不删除该元素

    相关代码为:

    @Override public boolean empty() { return this.hand!=null; //return this.size!=0;//两种方法都可以 } @Override public int size() { return this.size; } @Override public void pop() { this.size -- ; this.hand = this.hand.last;//指针移动 } @Override public T front() { return (T) this.hand.data;//返回数据 } @Override public T back() { return (T) this.next.data;//返回队尾数据 }

    代码测试

    public class SimulateQueueDemo { public static void main(String[] args) { IQueue<String> queue = new QueueImpl<>(); queue.push("A"); queue.push("B"); queue.push("C"); System.out.println("队首数据为:"+queue.front()); System.out.println("队尾数据为:"+queue.back()); while(queue.empty()){ System.out.print("弹出数据为:"+queue.front()); queue.pop(); System.out.println(",队列中数据剩余:"+queue.size()); } } }

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTrSbTYI-1602055132977)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201007151618514.png)]

    总结

    队列的出现是为了解决资源紧张的设计问题,因为资源不足,所以只能后进行排队依次处理,队列的出现解决的是数据缓存的问题。

    全部代码如下,也可以去gitee上下载

    package cn.tansanqinger.linked; interface IQueue<T>{ void push(T data);//压入数据 boolean empty();//如果队列为空返回true,否则返回false int size();//返回队列中元素的个数 void pop();//删除队列首元素但不返回其值 T front();//返回队首元素的值,但不删除该元素 T back();//返回队列尾元素的值,但不删除该元素 } class QueueImpl<T> implements IQueue<T>{ private Node hand;//队首 private Node next;//队尾 private int size;//队列长度 @Override public void push(T data) { Node node = new Node(data); if(this.hand==null){ this.hand = node; this.next = node; } else { this.next.last = node; this.next = this.next.last; } this.size ++ ; } @Override public boolean empty() { return this.hand!=null; //return this.size!=0;//两种方法都可以 } @Override public int size() { return this.size; } @Override public void pop() { this.size -- ; this.hand = this.hand.last;//指针移动 } @Override public T front() { return (T) this.hand.data;//返回数据 } @Override public T back() { return (T) this.next.data;//返回队尾数据 } private class Node<T>{//链表结点 private T data; private Node last;//保存下一个结点 private Node(T data){ this.data = data; } } } public class SimulateQueueDemo { public static void main(String[] args) { IQueue<String> queue = new QueueImpl<>(); queue.push("A"); queue.push("B"); queue.push("C"); System.out.println("队首数据为:"+queue.front()); System.out.println("队尾数据为:"+queue.back()); while(queue.empty()){ System.out.print("弹出数据为:"+queue.front()); queue.pop(); System.out.println(",队列中数据剩余:"+queue.size()); } } }

    其他数据存储知识点

    数据存储——单向链表

    数据存储——双向链表

    数据存储——实现ArrayList

    数据存储——栈(stack)

    Processed: 0.012, SQL: 8