数据结构 - 队列

数据结构 - 队列

概念及特性

  • 有序列表
    • 数组实现
    • 链表实现
  • 先进先出 - FIFO

在这里插入图片描述

使用场景

  • 银行业务排队 等

数组实现

  • 初步单向队列
package cn.com;

import java.util.Scanner;

public class ArrayQueQue {

    // 队列最大容量
    private int maxSize;
    // 队头指针
    private int front;
    // 队尾指针
    private int rear;

    private int[] array;

    public ArrayQueQue(int maxSize){
        this.maxSize = maxSize;
        this.array = new int[maxSize];
        // 起始指针下表也可以是0
        // front是队列头的前一位
        this.front = -1;
        // rear 是 队列尾的数据(注意理解:这里是队列尾的数据,没有前一位哦)
        this.rear = -1;
    }

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

    public boolean isFull(){
        return rear == maxSize-1;
    }

    public void add(int ele){
        if(isFull()){
            System.out.println("队列已满, 不能再添加数据");
            return;
        }
        rear ++;
        array[rear] = ele;
    }

    public int get(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        front ++;
        return array[front];
    }

    public int peek(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[front + 1];
    }

    public void show(){
        for (int i = 0; i < array.length; i ++){
            System.out.printf("array[%d]=%d\n", i, array[i]);
        }
    }

    // 主函数测试
    public static void main(String[] args) {
        ArrayQueQue arrayQueQue = new ArrayQueQue(3);
        System.out.println("操作菜单:");
        System.out.println("show : 展示队列数据");
        System.out.println("add : 增加数据到队列");
        System.out.println("get : 从队列取数据");
        System.out.println("peek : 查看当前队列头数据");
        System.out.println("exit : 退出");
        boolean flag = true;
        while (flag){
            System.out.println("请输入操作:");
            Scanner scanner = new Scanner(System.in);
            String operate = scanner.nextLine();
            switch (operate){
                case "show":
                    arrayQueQue.show();
                    break;
                case "add":
                    System.out.println("请输入数字:");
                    arrayQueQue.add(scanner.nextInt());
                    break;
                case "get":
                    try {

                        System.out.println("get 数据为:"+ arrayQueQue.get());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                case "peek":
                    try {

                        System.out.println("peek 的数据为:" + arrayQueQue.peek());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                default:
                    flag = false;
                    break;

            }
        }
        System.out.println("已退出···");
    }

}

以上队列存在的问题:

​ 队列只能使用一次,不能循环使用,故需要修改为循环队列

  • 循环队列 - 队列满的时候没有空值的数组表示
package cn.com;

import java.util.Scanner;

public class CycleArrayQueue {

    private int front;

    private int rear;

    private int[] cycleArr;

    private int maxSize;

    private boolean isFull;

    public CycleArrayQueue(int maxSize){
        this.maxSize = maxSize;
        cycleArr = new int[maxSize];
        // 指针初始值 - 0
        // 这个下表如果不赋值 也是默认为零,可以在此不进行赋值
        this.front = 0;
        this.rear = 0;
        this.isFull = false;
    }

    public boolean isEmpty(){
        return !isFull && front == rear;
    }

    public boolean isFull(){
        return isFull;
    }

    public int get(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        if(isFull){

            this.isFull = false;
        }
        int temp = cycleArr[front];
        front = (front + 1 + maxSize) % maxSize;
        return temp;
    }

    public void add(int a){
        if(isFull()){
            System.out.println("队列已满");
            return;
        }
        cycleArr[(this.rear + maxSize) % maxSize] = a;
        this.rear = (rear + 1 + maxSize) % maxSize;
        if(front == rear){
            this.isFull = true;
        }

    }

    public int peek(){
        return cycleArr[front];
    }


    public void show(){
        int len = maxSize;
        if(!isFull){
            len = (rear + maxSize - front) % maxSize;
        }
        for(int i = 0; i < len; i ++){
            System.out.printf("cycleArr[%d]=%d\n", (front + i) % maxSize, cycleArr[(front + i) % maxSize]);
        }
    }


    public static void main(String[] args) {
        CycleArrayQueue arrayQueQue = new CycleArrayQueue(3);
        System.out.println("操作菜单:");
        System.out.println("show : 展示队列数据");
        System.out.println("add : 增加数据到队列");
        System.out.println("get : 从队列取数据");
        System.out.println("peek : 查看当前队列头数据");
        System.out.println("exit : 退出");
        boolean flag = true;
        while (flag){
            System.out.println("请输入操作:");
            Scanner scanner = new Scanner(System.in);
            String operate = scanner.nextLine();
            switch (operate){
                case "show":
                    arrayQueQue.show();
                    break;
                case "add":
                    System.out.println("请输入数字:");
                    arrayQueQue.add(scanner.nextInt());
                    break;
                case "get":
                    try {

                        System.out.println("get 数据为:"+ arrayQueQue.get());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                case "peek":
                    try {

                        System.out.println("peek 的数据为:" + arrayQueQue.peek());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                default:
                    flag = false;
                    break;

            }
        }
        System.out.println("已退出···");
    }
}

  • 循环队列 - 队列满的时候存在一个空值的数组表示
package cn.com;

import java.util.Scanner;

public class CycleArrayQueue2 {

    // 最大队列数量
    private int maxSize;

    // 队列取值 指针 - 前指针
    private int front;

    // 队列赋值 指针 - 后指针
    private int rear;

    private int[] cycleArray;

    public CycleArrayQueue2(int maxSize){
        // 初始值
        this.maxSize = maxSize;
        this.cycleArray = new int[maxSize];
        // 前指针默认指向的初始位置:当然可以是任意的值(在maxSize指定的数组的长度范围即可)
        this.front = 0;
        // 后指针 默认指向后当前赋值的后一个下标,
        // 当没有开始没有任何一个值的, 初始应与front一样, 即当front = 2,的时候,rear = 2就行
        this.rear = 0;
        // 特别说明:
        // 这里的 front 和 rear 的赋值只是0.所以可以不写,因为int型,默认为0
    }

    // 判断是否为空
    public boolean isEmpty(){
        // 如果正常的情况下,这个判断可以判断为空,同样也符合,队列数组满的情况,因为满的时候,rear指向的是下一个,即rear 等于 front
        // 所以 这里当满的时候需要空一个位置,即 只有最后一个空的位置的时候,判定为满,以此区分空和满的判断条件
        return front == rear;
    }

    public boolean isFull(){
        return (rear + 1 + maxSize) % maxSize == front;
    }

    public void add(int a){
        if(isFull()){
            System.out.println("队列已满");
            return;
        }
        cycleArray[rear % maxSize] = a;
        rear = (rear + 1) % maxSize;
    }

    public int get(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int temp = cycleArray[front];
        front = (front + 1) % maxSize;
        return temp;
    }

    public int peek(){
        return cycleArray[front];
    }

    public void show(){
        for(int i = 0; i < (rear + maxSize - front)% maxSize; i++){
            System.out.printf("cycleArray[%d]=%d\n", (front + i) % maxSize, cycleArray[(front + i) % maxSize] );
        }
    }


    public static void main(String[] args) {
        CycleArrayQueue2 arrayQueQue = new CycleArrayQueue2(3);
        System.out.println("操作菜单:");
        System.out.println("show : 展示队列数据");
        System.out.println("add : 增加数据到队列");
        System.out.println("get : 从队列取数据");
        System.out.println("peek : 查看当前队列头数据");
        System.out.println("exit : 退出");
        boolean flag = true;
        while (flag){
            System.out.println("请输入操作:");
            Scanner scanner = new Scanner(System.in);
            String operate = scanner.nextLine();
            switch (operate){
                case "show":
                    arrayQueQue.show();
                    break;
                case "add":
                    System.out.println("请输入数字:");
                    arrayQueQue.add(scanner.nextInt());
                    break;
                case "get":
                    try {

                        System.out.println("get 数据为:"+ arrayQueQue.get());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                case "peek":
                    try {

                        System.out.println("peek 的数据为:" + arrayQueQue.peek());
                    }catch (Exception e){
                        e.printStackTrace();
                        System.out.println(e.getMessage());
                    }
                    break;
                default:
                    flag = false;
                    break;

            }
        }
        System.out.println("已退出···");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值