数据存储——队列(Queue)

数据存储——队列(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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值