1.2数据结构学习-队列

队列

1.描述:一种有序列表,可用数组或链表进行实现
2.存取原则:先进先出
3.种类:
	1).非环形队列:队列内不重复使用已取出数据的位置进行再次存储
	2).环形队列:队列内已取出数据的位置可继续进行重复存储

非环形队列

数组实现非环形队列思路

   1.设定maxSize为队列长度,则设定数组 array=Object[maxSize]
   2.为保持先进先出原则,则需记录[预存入下标]及[预读取下标],设预存入下标end,预读取下标front,初始值front=end=0(未存入)
   3.队列新增下一个元素则[预存入下标]end++
   4.队列读取下一个元素则[预读取下标]front++
   5.其中有效元素个数size=end-front
       如:存入5个元素,end=5,取出3个元素,front=3,则(size=5-3)==end-front
   6.仅当end-front==0时队列为空,end==maxSize队列为满

数组实现非环形队列DEMO

/**
 * @Auther: lxh
 * @Date: 2019/7/16/016 17:20
 * @Description: 数组实现队列
 */
public class ArrayQueue
{
    /**
     * 队列内部存储数组
     */
    private int[] arr;
    /**
     * 队列最大存储长度
     */
    private int maxSize;
    /**
     * 队列有效元素个数
     */
    private int size;
    /**
     * 队列当前预读取下标
     */
    private int front;
    /**
     * 队列当前预存入下标
     */
    private int end;

    public ArrayQueue(int maxSize)
    {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        size = 0;
        front = 0;
        end = 0;
    }

    /**
     * @param value 存入值
     * @desc :队列插入数据
     * 1.在数组对应预存入下标位置赋值
     * 2.有效元素数量+1
     * 3.预存入下标+1
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public void insert(int value)
    {
        if (isFull())
        {
            System.out.println("队列满,不能加入数据~");
            return;
        }
        size++;
        arr[end++] = value;
    }

    /**
     * @return : int 所取出数据
     * 1.读取数组对应预读取下标位置元素
     * 2.有效元素数量-1
     * 3.读取下标+1
     * @desc :队列取出数据
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public int remove()
    {
        // 判断队列是否空
        if (isEmpty())
        {
            System.out.println("队列空,不能取数据~");
            throw new RuntimeException("队列空,不能取数据");
        }
        size--;
        // front后移
        return arr[front++];
    }

    /**
     * @return boolean
     * @desc :判断队列是否为空
     * 1.仅当存储下标==读取下标时,说明存储的均已读取,此时为空
     * @author lxh
     * @date 2021/5/20 0020 1:35
     **/
    public boolean isEmpty()
    {
        return (front == end);
    }

    /**
     * @return boolean
     * @desc :判断队列是否已到达最大长度
     * 1.仅当存储下标==队列内数组最大下标时,此时队列已满
     * 1.仅当存储下标-读取下标时=队列最大长度时,说明可读取的有效元素数量已达到最大长度,此时队列已满
     * @author lxh
     * @date 2021/5/20 0020 1:35
     **/
    public boolean isFull()
    {
        return (end == maxSize);
    }

    public static void main(String[] args)
    {
        ArrayQueue arrayQueue = new ArrayQueue(5);
        System.out.println("---------------------");
        System.out.println("队列是否为空:" + arrayQueue.isEmpty());

        System.out.println("---------------------");
        System.out.println("开始加入数据:");
        int i = 0;
        while (!arrayQueue.isFull())
        {
            System.out.println("加入数据: " + i);
            arrayQueue.insert(i);
            i++;
        }

        System.out.println("---------------------");
        System.out.println("队列是否已满:" + arrayQueue.isFull());

        System.out.println("---------------------");
        System.out.println("测试队列已满是否可继续加入元素:");
        arrayQueue.insert(i + 1);

        System.out.println("---------------------");
        System.out.println("开始取出数据:");
        while (!arrayQueue.isEmpty())
        {
            System.out.println("取出数据: " + arrayQueue.remove());
        }


        System.out.println("---------------------");
        System.out.println("队列是否为空:" + arrayQueue.isEmpty());

        System.out.println("---------------------");
        System.out.println("测试队列已空是否可继续取出元素:");
        System.out.println(arrayQueue.remove());
        System.out.println("---------------------");
    }
}

结果

---------------------
队列是否为空:true
---------------------
开始加入数据:
加入数据: 0
加入数据: 1
加入数据: 2
加入数据: 3
加入数据: 4
---------------------
队列是否已满:true
---------------------
测试队列已满是否可继续加入元素:
队列满,不能加入数据~
---------------------
开始取出数据:
取出数据: 0
取出数据: 1
取出数据: 2
取出数据: 3
取出数据: 4
---------------------
队列是否为空:true
---------------------
测试队列已空是否可继续取出元素:
队列空,不能取数据~
Exception in thread "main" java.lang.RuntimeException: 队列空,不能取数据
	at com.lxh.structure.queue.ArrayQueue.remove(ArrayQueue.java:75)
	at com.lxh.structure.queue.ArrayQueue.main(ArrayQueue.java:143)

非环形队列

数组实现非环形队列思路

1.设定maxSize为队列长度,则设定数组 array=Object[maxSize]
2.为保持先进先出原则,则需记录[预存入下标]及[预读取下标],设预存入下标rear,预读取下标设预存入下标front,初始值front=rear=0(未存入)
3.队列新增下一个元素则存入下标rear++,考虑数组已满时会循环重新从数组首进行覆盖存储(已读取部分),则rear须对maxSize取余,即rear=(++rear)%maxSize
4.队列读取下一个元素则读取下标front++,考虑会已读取部分会重新存储,读取到数组尾部时须从数组首继续读取,,则front须对maxSize取余,即front=(++front)%maxSize
5.其中有效元素个数size=(rear-front+maxSize)%maxSize
       如:maxSize=5,存入4个元素,rear=4,取出3个元素,front=3,则(size=4-3)==(rear-front+maxSize)%maxSize
       如:maxSize=5,存入7个元素,rear=2,取出3个元素,front=3,则(size=7-3)==(rear-front+maxSize)%maxSize
6.避免rear=front时,难以判断是已存储满或存储为空,约定空出一个位置
7.仅当rear-front==0时队列为空
  仅当rear+1==front时队列为满

数组实现非环形队列DEMO

/**
 * @author: 李旭辉
 * @Date: 2019/8/5 0005 22:26
 * @description: 环形队列
 */
public class CircleArrayQueue
{
    /**
     * 队列内部存储数组
     */
    private int[] arr;
    /**
     * 队列最大存储长度
     */
    private int maxSize;
    /**
     * 队列当前预读取下标
     */
    private int front;
    /**
     * 队列当前预存入下标
     */
    private int rear;

    public CircleArrayQueue(int maxSize)
    {
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    /**
     * @return boolean
     * @desc :判断队列是否存储满
     * 1.仅当预存储下标已重复从数组头开始存储,且预存储下标距离预读取下标剩余1时,此时队列已满
     * @author lxh
     * @date 2021/5/20 0020 1:35
     **/
    public boolean isFull()
    {
        return (rear + 1) % maxSize == front;
    }

    /**
     * @return boolean
     * @desc :判断队列是否为空
     * 1.仅当存储下标==读取下标时,说明存储的均已读取,此时为空
     * @author lxh
     * @date 2021/5/20 0020 1:35
     **/
    public boolean isEmpty()
    {
        return rear == front;
    }

    /**
     * @param value 存入值
     * @desc :队列插入数据
     * 1.存入下标+1
     * 2.在数组对应预存入下标位置赋值
     * 2.有效元素数量+1
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public void insert(int value)
    {
        if (isFull())
        {
            System.out.println("队列满,不能加入数据~");
            return;
        }
        arr[rear] = value;
        rear = (rear + 1) % maxSize;
    }

    /**
     * @return : int 所取出数据
     * 1.读取数组对应预读取下标位置元素
     * 2.有效元素数量-1
     * 3.读取下标+1
     * @desc :队列取出数据
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public int getQueue()
    {
        if (isEmpty())
        {
            throw new RuntimeException("队列空,不能取数据");
        }
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    /**
     * @desc :显示队列的所有数据
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public void showQueue()
    {
        if (isEmpty())
        {
            System.out.println("队列空的,没有数据~~");
            return;
        }
        for (int i = front; i < front + size(); i++)
        {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    /**
     * @return : int 有效数据个数
     * @desc :求出当前队列有效数据的个数
     * @author lxh
     * @date 2021/5/20 0020 1:32
     **/
    public int size()
    {
        return (rear + maxSize - front) % maxSize;
    }


    public static void main(String[] args)
    {
        CircleArrayQueue circleArrayQueue = new CircleArrayQueue(5);
        System.out.println("---------------------");
        System.out.println("队列是否为空:" + circleArrayQueue.isEmpty());
        System.out.println("---------------------");
        System.out.println("开始加入数据:");
        int i = 0;
        while (!circleArrayQueue.isFull())
        {
            System.out.println("加入数据: " + i);
            circleArrayQueue.insert(i);
            i++;
        }
        System.out.println("---------------------");
        System.out.println("队列是否已满:" + circleArrayQueue.isFull());

        System.out.println("---------------------");
        System.out.println("此时队列元素明细为:");
        circleArrayQueue.showQueue();
        System.out.println("---------------------");
        System.out.println("测试队列已满是否可继续加入元素:");
        circleArrayQueue.insert(i + 1);

        System.out.println("---------------------");
        System.out.println("开始取出数据:");
        while (!circleArrayQueue.isEmpty())
        {
            System.out.println("取出数据: " + circleArrayQueue.getQueue());
        }
        System.out.println("---------------------");
        System.out.println("队列是否为空:" + circleArrayQueue.isEmpty());

        System.out.println("---------------------");
        System.out.println("测试队列已空是否可继续取出元素:");
        System.out.println(circleArrayQueue.getQueue());
        System.out.println("---------------------");

    }
}

结果

---------------------
队列是否为空:true
---------------------
开始加入数据:
加入数据: 0
加入数据: 1
加入数据: 2
加入数据: 3
---------------------
队列是否已满:true
---------------------
此时队列元素明细为:
arr[0]=0
arr[1]=1
arr[2]=2
arr[3]=3
---------------------
测试队列已满是否可继续加入元素:
队列满,不能加入数据~
---------------------
开始取出数据:
取出数据: 0
取出数据: 1
取出数据: 2
取出数据: 3
---------------------
队列是否为空:true
---------------------
测试队列已空是否可继续取出元素:
Exception in thread "main" java.lang.RuntimeException: 队列空,不能取数据
	at com.lxh.structure.queue.CircleArrayQueue.getQueue(CircleArrayQueue.java:90)
	at com.lxh.structure.queue.CircleArrayQueue.main(CircleArrayQueue.java:167)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值