菜鸟窝-数据结构与算法之数组实现队列

本文详细介绍了如何使用数组实现数据结构中的队列,包括普通队列和环形队列的实现思想及代码示例。在普通队列中,通过数组和两个指针维护队列状态,遵循先进先出原则。当数组空间不足时,通过转换为环形数组来提高空间利用率,避免数组无法复用的问题。文章还提供了完整的Java代码实现,并展示了如何在实际操作中进行入队、出队、查看队头元素等操作。
摘要由CSDN通过智能技术生成

categories:

  • 数据结构与算法
    tags:
  • 队列
    title: 数据结构与算法之队列
    date:

数据结构之队列

  1. 定义:有序列表,可以通过数组或者链表实现,遵循先入先出的原则

数组实现普通队列

  1. 示意图(从图中可以看出,通过队尾(指向最后一个元素)队首(指向第一个元素的前一位置)两个指针维护队列长度,加入队列时,front不变,rear++;出队列时rear不变,front++)
    在这里插入图片描述

    2.实现思想:

  • 入队列时

    • 尾指针rear向后移即rear+1,front==rear时(队列为空)

    • 若尾指针小于最大下标maxsize-1,则将数据存入,若等于则报队列满,否则无法存入

    • 代码实现

      public void addQueue(int x) {
              if (isFull()) {
                  System.out.println("队列已满,无法加入");
                  return;
              }
              //rear++;
              arr[++rear] = x;
          }
      
  • 出队列时

    • 头部指针front+1,

    • 若rear==front,队列为空,报错

    • 代码实现

      public int getQueue() {
              if (isEmpty()) {
                  throw new RuntimeException("队列空,无法获取");
              }
              return arr[++front];
          }
      
普通队列完整代码实现
package com.atguigu;

import java.util.Scanner;

public class arrayToQueue {
    public static void main(String[] args) {
        arrayQueue arrayQueue = new arrayQueue(3);
        char key = ' ';
        Scanner in = new Scanner(System.in);
        boolean tag = true;
        while (tag) {
            System.out.println("s:显示队列\n");
            System.out.println("e:退出程序\n");
            System.out.println("a:添加数据\n");
            System.out.println("g:取出数据\n");
            System.out.println("h:查看头部数据\n");
            key = in.next().charAt(0);
            switch (key) {
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("输入数字:");
                    int value = in.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int res = arrayQueue.getQueue();
                        System.out.println("取出的数据是" + res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        int res = arrayQueue.headQueue();
                        System.out.println("队列头数据是" + res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    in.close();
                    tag=false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出");
    }
}

class arrayQueue {
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;

    public arrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = -1;
        rear = -1;
    }

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

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

    //入队列
    public void addQueue(int x) {
        if (isFull()) {
            System.out.println("队列已满,无法加入");
            return;
        }
        //rear++;
        arr[++rear] = x;
    }

    //出队列
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,无法获取");
        }
        return arr[++front];
    }

    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空,没有数据");
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i] + " ");
        }
    }

    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,无法返回");
        }
        return arr[front + 1];
    }
}

  • 数组无法复用->将数组使用算法改进成环形数组达到空间利用的效果

数组模拟环形队列

1.思路

  • 调整front为指向队列的第一个元素,rear指向队列的最后一个元素的后一个位置,是为了空出一个空间作约定(否则无法判断是满是空)
  • 队列满的条件:(rear+1)%maxSize=front
  • 队列空的条件:rear==front
  • 队列中的有效数据个数:(rear+maxSize-front)%maxSize(rear比front小时代表已经跑了一圈)
    在这里插入图片描述

2.实现

package com.atguigu;

import java.util.Scanner;

public class circleQueue {

    public static void main(String[] args) {
        circleArrayQueue arrayQueue = new circleArrayQueue(4);
        char key = ' ';
        Scanner in = new Scanner(System.in);
        boolean tag = true;
        while (tag) {
            System.out.println("s:显示队列\n");
            System.out.println("e:退出程序\n");
            System.out.println("a:添加数据\n");
            System.out.println("g:取出数据\n");
            System.out.println("h:查看头部数据\n");
            key = in.next().charAt(0);
            switch (key) {
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("输入数字:");
                    int value = in.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int res = arrayQueue.getQueue();
                        System.out.println("取出的数据是" + res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        int res = arrayQueue.headQueue();
                        System.out.println("队列头数据是" + res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    in.close();
                    tag = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出");
    }
}

class circleArrayQueue {
    private int maxSize;//数组的最大容量
    private int front;//指向队列第一个元素
    private int rear;//指向队列最后一个元素的下一个位置
    private int[] arr;

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

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

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

    //入队列
    public void addQueue(int x) {
        if (isFull()) {
            System.out.println("队列已满,无法加入");
            return;
        }
        arr[rear] = x;
        rear = (rear + 1) % maxSize;
    }

    //出队列
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,无法获取");
        }
        int res = arr[front];
        front = (front + 1) % maxSize;
        return res;
    }

    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空,没有数据");
        }
        //从front开始遍历有效数据
        for (int i = front; i < front + size(); i++) {
            System.out.println("数组的显示为" + arr[i % maxSize] + " ");
        }
    }

    //求出有效数据个数
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }

    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,无法返回");
        }
        return arr[front % maxSize];
    }
}

更多详情请关注菜鸟窝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值