数据结构与算法系列(2)数据结构之队列详解

1、什么是队列?

队列(Queue)是一种常用的数据结构,队列(Queue)是一个有序列表,可以用数组或是链表来实现。队列(Queue)遵循先入先出的原则。即:先存入队列的数据,要先取出,后存入的要后取出。队列只允许在后端(tail)进行插入操作,在前端(head)进行出队列(删除)操作。

2、使用数组实现队列思路

队列是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明,如下图:

在这里插入图片描述

headtail分别记录队列前后端的下标,head会随着数据输出而改变,而 rear 则是随着数据输入而改变。

借助以下动态图,能更好的理解,队列的添加和删除。
在这里插入图片描述

3、简单队列代码实现

基于java实现简单队列。

public class ArrayQueue {
    /**
     * 队列头部
     */
    private int head;
    /**
     *队列尾部
     */
    private int tail;

    /**
     * 存放数据
     */
    private int[] array;

    /**
     *
     */
    private int capacity;


    /**
     * 初始化数组
     * @param capacity
     */
    public ArrayQueue(int capacity) {
        this.capacity = capacity;
        //初始化数组
        this.array=new int[capacity];
    }

    /**
     * 入队
     */
    public void add(int n){
       if (isFull()){
           throw new RuntimeException("队列已经满了");
       }
       array[tail]=n;
       //队尾后移
       tail++;
    }

    /**
     * 出队列
     * @return
     */
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int value=array[head];
        //头部指针后移
        head++;
        return value;
    }

    /**
     * 获取队列头数据
     * @return
     */
    public int getFirst(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[head];
    }

    /**
     * 获取队列头数据
     * @return
     */
    public int getLast(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[tail];
    }

    /**
     * 队列是否为空
     * @return
     */
    public boolean isEmpty(){
        return head==tail;
    }

    /**
     * 队列是否满了
     * @return
     */
    public boolean isFull(){
       return tail==capacity;
    }

}

测试代码

public static void main(String[] args) {
        ArrayQueue arrayQueue=new ArrayQueue(5);
        arrayQueue.add(1);
        arrayQueue.add(2);
        arrayQueue.add(3);
        arrayQueue.add(4);
        arrayQueue.add(5);

        System.out.println(arrayQueue.pop());

        System.out.println(arrayQueue.getFirst());
        arrayQueue.add(6);
    }

上面实现的简单队列,有如下问题:队列只能使用一次就不能用,即:当队列添加数据加满后,即使有数据出队列了,也不能再添加新的数据。下面介绍的环形队列,可以解决此问题。

4、环形队列

public class CirleArrayQueue {

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
         CirleArrayQueue cirleArrayQueue=new CirleArrayQueue(6);
         cirleArrayQueue.add(1);
        cirleArrayQueue.add(2);
        cirleArrayQueue.add(3);
        cirleArrayQueue.add(4);
        cirleArrayQueue.add(5);
        System.out.println("原始队列中的数据~~~~");
        cirleArrayQueue.list();
        System.out.println("出队列的数据:"+ cirleArrayQueue.pop());
        cirleArrayQueue.list();
        System.out.println("添加数据后,队列中的数据~~~~~");
        cirleArrayQueue.add(6);
        cirleArrayQueue.list();

    }
    /**
     * 队列头部
     */
    private int head;
    /**
     *队列尾部
     */
    private int tail;

    /**
     * 存放数据
     */
    private int[] array;

    /**
     *
     */
    private int capacity;


    /**
     * 初始化数组
     * @param capacity
     */
    public CirleArrayQueue(int capacity) {
        this.capacity = capacity;
        //初始化数组
        this.array=new int[capacity];
    }

    /**
     * 入队
     */
    public void add(int n){
        if (isFull()){
            throw new RuntimeException("队列已经满了");
        }
        array[tail]=n;
        //因为是环形队列,使用取模
        tail=(tail+1)%capacity;
    }

    /**
     * 出队列
     * @return
     */
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int value=array[head];
        //头部指针后移
        head=(head+1)%capacity;
        return value;
    }

    /**
     * 获取队列头数据
     * @return
     */
    public int getFirst(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[head];
    }

    /**
     * 获取队列头数据
     * @return
     */
    public int getLast(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[tail];
    }

    /**
     * 队列是否为空
     * @return
     */
    public boolean isEmpty(){
        return head==tail;
    }

    /**
     * 队列是否满了
     * @return
     */
    public boolean isFull(){
        return (tail+1)%capacity==head;
    }

    public int size(){
        return (tail+capacity-head)%capacity;
    }

    public void list(){
        for (int i = head; i <head+size() ; i++) {
            if (array[i]!=0)
              System.out.println(array[i]);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值