java 数组实现单项队列和环形队列!

数组实现队列:

  • 普通单项队列
  • 环形队列

一、实现普通队列

在这里插入图片描述
1) 将尾指针往后移:rear+1 , 当 front == rear 【空】
2) 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == maxSize - 1[队列满]

public static void main(String[] args) {
    ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
    Scanner scanner = new Scanner(System.in);
    char key = ' '; //接收用户输入
    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':
                mArrayQueueTest.showQueue();
                break;
            case 'a':
                System.out.println("输出一个数");
                int value = scanner.nextInt();
                mArrayQueueTest.addQueue(value);
                break;
            case 'g': //取出数据
                try {
                    int res = mArrayQueueTest.getQueue();
                    System.out.printf("取出的数据是%d\n", res);
                } catch (Exception e) {
                    // TODO: handle exception
                    System.out.println(e.getMessage());
                }
                break;
            case 'h': //查看队列头的数据
                try {
                    int res = mArrayQueueTest.peek();
                    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;
        }
    }
}


/**
 1. 数组实现单项队列
 2. 1) 将尾指针往后移:rear+1 , 当 front == rear 【空】
 3. 2) 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。
 4. 3) 判断队列 满没满   end == mMaxSize - 1
 5. 头指针在队列的前一个位置。是这么设计的(你也可以放在当前头的位置)
*/
static class ArrayQueueTest{
    // 头指针
    public int head = -1;
    // 尾指针
    public int end  = -1;
    // 队列
    public int[] mQueue;
    // 队列的最大容量
    public int mMaxSize;
    public ArrayQueueTest(int mMaxSize) {
        this.mMaxSize = mMaxSize;
        mQueue = new int[mMaxSize];
    }
    /**
     * 添加数据
     */
    public void addQueue(int data){
        if(isFull()) {
            System.out.print("队列已经满了");
            return;
        }
        // 尾指针往后加
        end++;
        mQueue[end] = data;
    }
    /**
     * 取数据
     */
    public int getQueue(){
        if(isEmpty()) {
            throw new RuntimeException("队列为空哦~~~");
        }
        // 头指针往后移
        head++;
        return mQueue[head];
    }
    /**
     * 查看头数据
     */
    public int peek(){
        if(isEmpty()) {
            throw new RuntimeException("队列为空哦~~~");
        }
        return mQueue[head + 1];
    }
    /**
     * 遍历数组
     */
    public void showQueue(){
        if(isEmpty()) {
            System.out.println("队列空的,没有数据~~");
            return;
        }
        for(int i = 0; i < mQueue.length; i++) {
            System.out.println(i+" ------>  "+mQueue[i]);
        }
    }
    /**
     * 判断队列是否为空
     * @return
     */
    public boolean isEmpty(){
        return head == end;
    }
    /**
     * 判断队列满没满
     */
    public boolean isFull(){
        return end == mMaxSize - 1;
    }
}

二、实现环形队列

分析说明:
1、尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意 (rear + 1) %maxSize == front 满]

2、 rear == front [空]

3、为什么要预留一个空间呢?因为这样比较好判断是不是满了,是不是空(若不使用空节点。当font-rear=-1时,不能判断是空还是满.这时可能会多一些处理语句。比如:在出队列时,如果发现font=rear的情况。在出队列以后将font=rear=-1.判断为空的唯一条件就是font=rear=-1)

4、分析示意图:
在这里插入图片描述

public static void main(String[] args) {
    ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
    Scanner scanner = new Scanner(System.in);
    char key = ' '; //接收用户输入
    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':
                mArrayQueueTest.showQueue();
                break;
            case 'a':
                System.out.println("输出一个数");
                int value = scanner.nextInt();
                mArrayQueueTest.addQueue(value);
                break;
            case 'g': //取出数据
                try {
                    int res = mArrayQueueTest.getQueue();
                    System.out.printf("取出的数据是%d\n", res);
                } catch (Exception e) {
                    // TODO: handle exception
                    System.out.println(e.getMessage());
                }
                break;
            case 'h': //查看队列头的数据
                try {
                    int res = mArrayQueueTest.peek();
                    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;
        }
    }
}


/**
* 数组实现环形队列
* *) 队列尾部空余一个空间
* 1)判断队列满没满  (end + 1 )% size == head   尾指针+ 1(预留空间) % size == 头指针说明数组满了
* 2)判断队列有效个数 (end + size - head) % size
*/
static class ArrayCircleQueue{
    // 头指针
    public int head;
    // 尾指针
    public int end;
    // 队列
    public int[] mQueue;
    // 队列的最大容量
    public int mMaxSize;
    public ArrayCircleQueue(int mMaxSize) {
        this.mMaxSize = mMaxSize;
        mQueue = new int[mMaxSize];
    }
    /**
     * 添加数据
     */
    public void addQueue(int data){
        if(isFull()) {
            System.out.print("队列已经满了");
            return;
        }
        mQueue[end] = data;
        // 尾指针计算
        end = (end + 1) % mMaxSize;
    }
    /**
     * 取数据
     */
    public int getQueue(){
        if(isEmpty()) {
            throw new RuntimeException("队列为空哦~~~");
        }
        // 头指针往后移
        int value = mQueue[head];
        head = (head + 1) % mMaxSize;
        return value;
    }
    /**
     * 查看头数据
     */
    public int peek(){
        if(isEmpty()) {
            throw new RuntimeException("队列为空哦~~~");
        }
        return mQueue[head];
    }
    // 显示队列的所有数据
    public void showQueue() {
        // 遍历
        if (isEmpty()) {
            System.out.println("队列空的,没有数据~~");
            return;
        }
        // 思路:从front开始遍历,遍历多少个元素
        for (int i = head; i < head + size() ; i++) {
            System.out.printf("arr[%d]=%d\n", i % mMaxSize, mQueue[i % mMaxSize]);
        }
    }
    // 求出当前队列有效数据的个数
    public int size() {
        // rear = 2
        // front = 1
        // maxSize = 3
        return (end + mMaxSize - head) % mMaxSize;
    }
    /**
     * 判断队列是否为空
     * @return
     */
    public boolean isEmpty(){
        return head == end;
    }
    /**
     * 判断队列满没满
     */
    public boolean isFull(){
        return head == (end + 1) % mMaxSize;
    }
}
发布了51 篇原创文章 · 获赞 78 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_39079048/article/details/102914996