近期学习数据结构笔记=====>队列

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了近期学习数据结构笔记=====>队列相关的知识,希望对你有一定的参考价值。

学习来源–>传送门–>尚硅谷Java数据结构与java算法(Java数据结构与算法)


队列:先进先出结构
是有序的列表; 可以用数组/链表存储数据;

例如->数组存储结构; maxSize:最大容量;

对于数组存储的话,就考虑数组的索引问题,数组是由0索引开始的,那么实际上这个队列在 (maxSize -1)的时候就满了;

在向队列存储数据的时候,首先要考虑判断队列是否满了;添加后队列的个数要增加1个;
删除的时候还要考虑让队列的元素个数减少1个;

队列为空的情况–> 头指针和尾指针 相等时;

数组模拟队列实现

package day02forqueue;

import java.util.Arrays;

/**
 * @author by CSDN@小智RE0
 * @date 2021-10-30 22:15
 * 用队列模拟实现数组;
 */
public class QueueByArray {
    //队列的容量;
    private final int capacity;
    //头部指针,实际指向队头的前一个位置;
    private int front;
    //尾巴指针;实际指向队列的最后一个位置;
    private int rear;
    //用数组存储数据;
    private final int[] dataArray;

    //初始化;指定容量;
    public QueueByArray(int capacity) {
        this.capacity = capacity;
        this.front = -1;
        this.rear  = -1;
        this.dataArray = new int[capacity];
    }

    //判断队列是否为空;
    public boolean isEmpty(){
        //头指针和尾指针在一块时,队列就是空的;
        return front == rear;
    }

    //判断队列满了没; 尾指针指向最后一个时;就满了;
    public boolean isFull(){
        return rear == capacity - 1;
    }

    //添加元素进队列;
    public void addQueue(int data){
        //先判断队列是否满了;
        if(isFull()){
            System.out.println("队列已满,拒绝入队");
            return;
        }
        //尾指针向后移动;
        rear ++;
        dataArray[rear] = data;
    }

    //模拟元素出队; 实际上元素还在  获取到队列的数据;
    public int removeQueue(){
        //先判断队列为空吗;抛出异常;
        if(isEmpty()){
            throw  new RuntimeException("队列为空,拒绝获取");
        }
        //头指针后移;
        front++;
        return dataArray[front];
    }

    //输出队列;
    public void toGetAll(){
        //判空;
        if(isEmpty()){
            System.out.println("空队列,拒绝遍历");
            return;
        }
        Arrays.stream(dataArray).forEach(System.out::println);
    }

    //获取队头;
    public int getHead(){
        //判空;
        if(isEmpty()){
            throw  new RuntimeException("空队列,拒绝取元素");
        }
        return dataArray[front+1];
    }
}    

测试;

public static void main(String[] args) {
        QueueByArray queueByArray = new QueueByArray(5);
        queueByArray.addQueue(12);
        queueByArray.addQueue(15);
        queueByArray.addQueue(6);
        queueByArray.addQueue(7);
        queueByArray.addQueue(8);
        //已经添加5个了;拒绝添加;
        //queueByArray.addQueue(3);

        //仅获取数据; 看着是被取走了;只是指针后移了而已;
        System.out.println("获取数据->"+queueByArray.removeQueue());

        //获取队头;
        System.out.println("队头->"+queueByArray.getHead());
        //遍历
        queueByArray.toGetAll();
    }

/*

获取数据->12
队头->15
12
15
6
7
8

*/

上面的队列,虽然说有基础的功能,但是还是有很大问题的;比如说它并不会真正地删除数据;

模拟环形队列实现

为了达到队列的复用;

指针的含义改变一下;
头指针就指定指向队列的头元素;
尾指针指向队尾的后一个位置; 为什么不是直接指向最后一个位置呢;
这是个环形的队列,尾指针有可能会跑前面来;

队满的判断条件也要改变;
当 (尾指针 +1 ) % 容量 == 头指针 ;

此时队列的有效数据个数; (尾指针 + 容量 - 头指针) % 容量;
注意有效数据的个数会比真实容量少一个

package day02forqueue;

/**
 * @author by CSDN@小智RE0
 * 模拟环形队列
 */
public class CircleQueueByArray {
    // 容量,头指针,尾指针,数据容器;
    private int capacity;
    private int front;
    private int rear;
    private int[] dataArray;

    //初始化;略有不同;
    public CircleQueueByArray(int capacity) {
        this.capacity = capacity;
        dataArray = new int[capacity];
        this.front = 0;
        this.rear = 0;
    }

    //判空;
    public boolean isEmpty(){
        return front == rear;
    }

    //是否满队列;
    public boolean isFull(){
        return (rear + 1)%capacity == front;
    }

    //入队操作;
    public void addQueue(int data){
        //判断是否满;
        if(isFull()){
            System.out.println("队列已满,不能入队");
            return;
        }
        //正常入队;
        dataArray[rear] = data;
        //尾指针后移;注意这是环形队列;
        rear = (rear+1) % capacity;
    }

    //取出数据元素;
    public int getData(){
        //先判空;
        if(isEmpty()){
            throw  new RuntimeException("队列为空,无法取出元素");
        }
        //正常取出; 注意要先把头指针指向的值存起来后再取出;
        // 由于是环形队列,需要考虑到头指针转一圈可能还会回来; 所以不能直接让它++后移;
        int temp = dataArray[front];

        front  = (front+1)%capacity;
        return temp;
    }

    //获取队列的实际元素个数; 注意实际元素个数会比 容量少一个 ; 比如说创建了5个长度的,实际最多只能存放四个;
    public int getSize(){
        return (rear + capacity - front ) % capacity;
    }

    //遍历;
    public void toGetAll(){
        //判空;
        if(isEmpty()){
            System.out.println("空队列,拒绝遍历");
            return;
        }
        //这里就要算有效元素的个数了;
        for (int i = front; i <front+getSize() ; i++) {
            System.out.printf("dataArray[%d]=%d\\n",i % capacity ,dataArray[i % capacity]);
        }
    }

    //获取头元素;
    public int getHead(){
        //判空;
        if(isEmpty()){
            throw new RuntimeException("队列为空,不可取");
        }
        //取到即可;
        return dataArray[front];
    }
}    

测试使用

public static void main(String[] args) {
        CircleQueueByArray circleQueueByArray = new CircleQueueByArray(5);
        circleQueueByArray.addQueue(12);
        circleQueueByArray.addQueue(15);
        circleQueueByArray.addQueue(6);
        circleQueueByArray.addQueue(7);
        System.out.println("---------------------------------------");
        //实际只存了4个;
        circleQueueByArray.addQueue(8);

        System.out.println("实际元素个数->"+circleQueueByArray.getSize());
        System.out.println("获取头元素->"+circleQueueByArray.getHead());
        //遍历;
        circleQueueByArray.toGetAll();

        System.out.println("--------------取出一个元素--------------------");
        //取出一个元素; 然后查看实际个数与队头;
        System.out.println("取出元素--->"+circleQueueByArray.getData());


        System.out.println("实际元素个数->"+circleQueueByArray.getSize());
        System.out.println("获取头元素->"+circleQueueByArray.getHead());
        //遍历
        circleQueueByArray.toGetAll();

        System.out.println("----------------添加一个元素-------------------");
        //添加;
        circleQueueByArray.addQueue(8);
        //遍历;
        circleQueueByArray.toGetAll();
    }
---------------------------------------
队列已满,不能入队
实际元素个数->4
获取头元素->12
dataArray[0]=12
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
--------------取出一个元素--------------------
取出元素--->12
实际元素个数->3
获取头元素->15
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
----------------添加一个元素-------------------
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
dataArray[4]=8

以上是关于近期学习数据结构笔记=====>队列的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

数据结构学习笔记——顺序存储结构实现循环队列

数据结构学习笔记(栈队列)整理与总结

数据结构学习笔记(栈队列)整理与总结

数据结构学习笔记——顺序存储结构实现循环队列

数据结构学习笔记——队列的基本知识和顺序存储结构实现队列