数据结构之队列

一,数组模拟队列

  规定头指针front和尾指针rear都为-1,front=-1表示头指针指向队头的前一个位置,尾指针rear=-1表示指向队尾,这两句话要好好的理解,

  maxSize为队列的大小

  arr[ ]使用来存储数据的数组,大小由maxSize来定,

  判断队列是否为空:当队尾和队头合并则代表队列为空,rear == front

  判断队列是否已满:当队尾的索引等于队列长度-1,因为索引从0开始,所以队列的长度要-1才和队尾索引相等,rear == maxSize-1

    入队:先判断是否已满,不满的话尾指针后移一个位置(rear++),然后将元素放入数组

  出队:判断队列是否为空,不为空的话头指针后移(front++)

代码:

  1 package Queue;
  2 
  3 import java.util.Scanner;
  4 
  5 public class ArrayQueue {
  6 
  7     public static void main(String[] args) {
  8         ArrayQueue arrayQueue = new ArrayQueue(6);
  9         Scanner scanner = new Scanner(System.in);
 10         char key = ' ';
 11         boolean loop = true;
 12         while (loop) {
 13             System.out.println("a 入队");
 14             System.out.println("r 出队");
 15             System.out.println("g 遍历队列");
 16             System.out.println("h 查看队头元素");
 17             key = scanner.next().charAt(0);//接收一个字符串
 18             switch (key) {
 19                 case 'a':
 20                     System.out.println("输入一个数");
 21                     int value = scanner.nextInt();
 22                     arrayQueue.addQueue(value);
 23                     break;
 24                 case 'r':
 25                     try {
 26                         int removeNum = arrayQueue.removeQueue();
 27                         System.out.println("取出的数据为:" + removeNum);
 28                     } catch (Exception e) {
 29                         System.out.println(e.getMessage());
 30                     }
 31                     break;
 32                 case 'g':
 33                     try {
 34                         arrayQueue.getAllQueue();
 35                     } catch (Exception e) {
 36                         System.out.println(e.getMessage());
 37                     }
 38                     break;
 39                 case 'h':
 40                     try {
 41                         int headNum = arrayQueue.headQueue();
 42                         System.out.println("队头为:"+headNum);
 43                     }catch (Exception e){
 44                         System.out.println(e.getMessage());
 45                     }
 46             }
 47         }
 48     }
 49 
 50     int maxSize;
 51     int rear;
 52     int front;
 53     int arr[];
 54 
 55     public ArrayQueue(int arrMaxSize){
 56         maxSize = arrMaxSize;
 57         rear = -1;
 58         front = -1;
 59         arr = new int[maxSize];
 60     }
 61 
 62     //判断队列是否为空
 63     public boolean isEmpty(){
 64         return rear == front;
 65     }
 66 
 67     //判断队列是否已满
 68     public boolean isFull(){
 69         return rear == maxSize-1;
 70     }
 71 
 72     //入队
 73     public void addQueue(int num){
 74         if (isFull()){
 75             System.out.println("队列满的");
 76             return;
 77         }
 78         rear++;
 79         arr[rear] = num;//入队
 80     }
 81 
 82     //出队(单个元素)
 83     public int removeQueue(){
 84         if (isEmpty()){
 85             throw new RuntimeException("队列没有元素");
 86         }
 87         front++;
 88         return arr[front];
 89     }
 90 
 91     //遍历队列所有元素
 92     public void getAllQueue(){
 93         if (isEmpty()){
 94             throw new RuntimeException("队列为空");
 95         }
 96         for (int i = 0 ; i <= arr.length ; i++){
 97             System.out.println("队列元素下标:"+i+"   "+"队列元素值:"+arr[i]);
 98         }
 99     }
100 
101     //查看队头元素
102     public int headQueue(){
103         if (isEmpty()){
104             throw new RuntimeException("队列为空");
105         }
106         return arr[front+1];
107     }
108 }
View Code

 但是上述代码存在一个问题,数组使用过一次就不能使用了(因为头指针front和尾指针rear都指向了入队口,虽然里面还有很多空间,但是不能用,是一个“假的”满队列),如果要复用,则应该改造成环形队列

二:环形队列

    思路:对front变量的含义做调整,front指向队列第一个元素,初始值为0,rear指向最后一个元素的前一个元素,留出一个空位作为约定,rear初始值为0

  判断队满:(rear+1)%maxSize == front;

  上图:rear=4,front=0,maxSize=5

  (4+1)%5=0

  判断队空:rear == front

    rear和front初始化都为0,如果rear==front,为空

    队列中元素个数:(rear+maxSize-front)%maxSize

    如上队满图:(4+5-0)%5 = 4

代码:

  1 package Queue;
  2 
  3 import java.util.Scanner;
  4 
  5 public class CircleArrayQueue {
  6     public static void main(String[] args) {
  7         CircleArray arrayQueue = new CircleArray(4);
  8         Scanner scanner = new Scanner(System.in);
  9         char key = ' ';
 10         boolean loop = true;
 11         while (loop) {
 12             System.out.println("a 入队");
 13             System.out.println("r 出队");
 14             System.out.println("g 遍历队列");
 15             System.out.println("h 查看队头元素");
 16             key = scanner.next().charAt(0);//接收一个字符串
 17             switch (key) {
 18                 case 'a':
 19                     System.out.println("输入一个数");
 20                     int value = scanner.nextInt();
 21                     arrayQueue.addQueue(value);
 22                     break;
 23                 case 'r':
 24                     try {
 25                         int removeNum = arrayQueue.removeQueue();
 26                         System.out.println("取出的数据为:" + removeNum);
 27                     } catch (Exception e) {
 28                         System.out.println(e.getMessage());
 29                     }
 30                     break;
 31                 case 'g':
 32                     try {
 33                         arrayQueue.getAllQueue();
 34                     } catch (Exception e) {
 35                         System.out.println(e.getMessage());
 36                     }
 37                     break;
 38                 case 'h':
 39                     try {
 40                         int headNum = arrayQueue.headQueue();
 41                         System.out.println("队头为:"+headNum);
 42                     }catch (Exception e){
 43                         System.out.println(e.getMessage());
 44                     }
 45             }
 46         }
 47     }
 48 
 49 }
 50 class CircleArray{
 51     int maxSize;
 52     int rear;
 53     int front;
 54     int arr[];
 55 
 56     public CircleArray(int arrMaxSize){
 57         maxSize = arrMaxSize;
 58         arr = new int[maxSize];
 59         front = 0;
 60         rear = 0;
 61     }
 62     //判断队列是否为空
 63     public boolean isEmpty(){
 64         return rear == front;
 65     }
 66     //队列是否已满
 67     public boolean isFull(){
 68         return (rear+1)%maxSize == front;
 69     }
 70 
 71     //入队
 72     public void addQueue(int num){
 73         if (isFull()){
 74             System.out.println("队列满的");
 75             return;
 76         }
 77         arr[rear] = num;//入队
 78         rear = (rear+1)%maxSize;
 79     }
 80     //出队(单个元素)
 81     public int removeQueue(){
 82         if (isEmpty()){
 83             throw new RuntimeException("队列没有元素");
 84         }
 85         int value = arr[front];
 86         front = (front + 1) % maxSize;
 87         return value;
 88     }
 89 
 90     //元素有效个数
 91     public int size(){
 92         return (rear+maxSize-front)%maxSize;
 93     }
 94 
 95     //遍历队列所有元素
 96     public void getAllQueue(){
 97         if (isEmpty()){
 98             throw new RuntimeException("队列为空");
 99         }
100         //从front开始遍历
101         for (int i = front ; i <= size()  ; i++){
102             System.out.printf("arr[%d]=%d
",i % maxSize,arr[i % maxSize]);
103         }
104     }
105 
106     //查看队头元素
107     public int headQueue(){
108         if (isEmpty()){
109             throw new RuntimeException("队列为空");
110         }
111         return arr[front];
112     }
113 
114 }
View Code

环形队列还不是很清楚

生命不止,折腾不息
原文地址:https://www.cnblogs.com/steakliu/p/11418398.html