环形Queue队列

环形Queue队列

为了解决数组队列无法复用的问题。采用的思路是取模:%
和之前的queue相比,思路发生了改变。
现在的rear:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定
现在的front:front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
他们的初始值我们现在也设为0。因为rear是后一个元素,front为第一个元素,所以初始值为0。之前的正常的队列,rear是当前元素,front为第一个元素的前一个元素,所以初始值为-1。

  1. 队列满的条件是:(rear+1)%MaxSize==front
    //(real+1)最后一个元素在real,因为思路是始终空出一个元素,所以+1取模相等时,队列就满了
  2. 队列空的条件是:rear=front    //初始的时候相等,队列为空
  3. 队列中的实际有效个数为:(rear+MaxSize-front)%MaxSize

代码实现:

//使用数组模拟队列   编写一个ArrayQueue
class circleArray{
    private int MaxSize;   //队列最大容量
    private int front;     //队列头
    private int rear;      //队列尾部
    private  int[] arr;    //该数组用于存放数据,模拟队列

    //创建队列的构造器
    public circleArray(int arrMaxSize)
    {
        MaxSize=arrMaxSize;
        arr=new int[MaxSize];
        //front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
        //front 的初始值 = 0
        front=0;
        //rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
        //rear 的初始值 = 0
        rear=0;
    }

    //判断队列是否满
    public boolean issFull(){
        return (rear+1)%MaxSize==front;
    }

    //判断队列是否为空
    public boolean issEmpty(){
        return rear==front;
    }

    //添加数据到队列
    public void addQueue(int n)
    {
        //判断队列是否满
        if (issFull())
        {
            System.out.println("队列满,不能加入数据");
            return;
        }
        //直接将数据加入
        arr[rear]=n;
        //将rear后移,考虑取模   因为不能无线增长
        rear=(rear+1)%MaxSize;
    }

    //获取队列的数据,出队列
    public int getQueue()
    {
        //判断队列是否空
        if (issEmpty())
        {
            //抛异常处理
            throw new RuntimeException("队列为空");
        }
        //这里需要分析出front是指向队列的第一个元素
        //1.先把front对应的值保存到临时变量
        //2.将front后移
        //3.将临时保存的变量返回
        int value=arr[front];
        front= (front+1)%MaxSize;      
        return value;
    }

    //显示队列的所有数据
    public void showQueue(){
        if (issEmpty())
        {
            System.out.println("队列为空");
            return;
        }
        //思路:从front开始遍历,遍历多少个元素
        //(rear+maxsize-front)%maxsize
        for (int i=front;i<front+size();i++)
        {
            System.out.print("a["+i%MaxSize+"]:"+arr[i % MaxSize]+" ");
        }
        System.out.println();
    }
    //求出当前队列的有效数据
    public int size(){
        return (rear+MaxSize-front)%MaxSize;
    }
    //显示队列的头数据,不是取数据
    public int headQueue(){
        if (issEmpty())
        {
            System.out.println("队列为空");
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }
}

可用以下代码来操作:

        circleArray queue = new circleArray(4);   //设置为4,其队列的有效数据为3
        char key = ' '; //接收用户输入
        Scanner scanner = new Scanner(System.in);//
        boolean loop = true;
        //输出一个菜单
        while(loop) {
            System.out.println("s(show): 显示队列");
            System.out.println("e(exit): 退出程序");
            System.out.println("a(add): 添加数据到队列");
            System.out.println("g(get): 从队列取出数据");
            System.out.println("h(head): 查看队列头的数据");
            key = scanner.next().charAt(0);//接收一个字符
            switch (key) {
                case 's':
                    queue.showQueue();
                    break;
                case 'a':
                    System.out.println("输出一个数");
                    int value = scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'g': //取出数据
                    try {
                        int res = queue.getQueue();
                        System.out.printf("取出的数据是%d\n", res);
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h': //查看队列头的数据
                    try {
                        int res = queue.headQueue();
                        System.out.printf("队列头的数据是%d\n", res);
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e': //退出
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }

        System.out.println("程序退出~~");

你可能感兴趣的:(数据结构)