Data structure and algorithm exercises (2) Array simulation queue


1. Queue

队列是一个有序列表,可以用数组或链表来实现
遵循先入先出的原则
在队尾插入元素叫做入队,对头删除元素叫做出队。

2. Array implementation queue

insert image description hereIdea:

  • Use front and rear to record the subscripts before and after the queue. Initializing front=-1 means pointing to the head of the queue (the previous position of the queue head), and rear=-1 points to the end of the queue (the last data of the queue).
  • If the tail pointer rear is less than the maximum subscript of the queue MaxSize-1, then rear + 1 tail pointer moves backward. If rear = MaxSize-1, the queue is full.
  • If out of the queue, the head pointer moves backward by front+1, if rear=front. The queue is empty.

Code:

package Que;
/*
 * 数组模拟队列
 * */
import java.util.Scanner;
public class ArrToQue {
    
    
    public static void main(String[] args) {
    
    
        //创建一个尺寸为5的队列
        Queue queue = new Queue(5);
        Scanner scanner = new Scanner(System.in);
        char key=' ';
        boolean loop=true;
        while (loop){
    
    
            System.out.println("d:显示队列");
            System.out.println("e:退出程序");
            System.out.println("a:添加数据到队列");
            System.out.println("b:从队列取出数据");
            System.out.println("c:查看队列头部数据");
            key=scanner.next().charAt(0); //获取用户输入的第一个字符
            switch (key){
    
    
                case 'a':
                    System.out.println("请输入一个数");
                    int value= scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'b':
                    try{
    
    
                        int res = queue.delQue();
                        System.out.println("去除的数据为:"+res);
                    }catch (Exception e){
    
    
                        System.out.println(e.getMessage());//低下抛出异常,这里捕捉异常信息
                    }
                    break;
                case 'c':
                    try{
    
    
                        int res = queue.headQue();
                        System.out.println("头数据为:"+res);
                    }catch (Exception e){
    
    
                        System.out.println(e.getMessage());//低下抛出异常,这里捕捉异常信息
                    }
                    break;
                case 'd':
                        queue.showQue();
                        break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
    }
}

/*定义一个队列
* */
class Queue{
    
    
  int maxSize ;
  int front;
  int rear;
  int[] arr;
  //通过构造方法初始化
    public Queue(int maxSize) {
    
    
        this.maxSize = maxSize;
        this.front = -1;
        this.rear = -1;
        this.arr = new int[maxSize];
    }
    //判断队列是否为空
    public  boolean isNull(){
    
    
        //初始化都为-1为true,队列数据都取完front=rear=maxSize-1
        return front==rear;
    }
    //判断队列是否是满的
    public boolean isFull(){
    
    
        return rear==maxSize-1;
    }
    //队列中添加数据
    public void  addQueue(int data){
    
    
        //先判断队列是不是满的
        if(isFull()){
    
    
            //抛出运行时异常
            System.out.println("队列已经满了");
        }else {
    
    
            rear++;
            arr[rear]=data;
        }
    }
    //从队列中删除数据
    public  int delQue(){
    
    
        //首先判断队列是否为空
        if (isNull()){
    
    
            throw new RuntimeException("队列为空");
            //System.out.println("队列为空");
        }else {
    
    
            front++;
            return arr[front];//返回删除的数据
        }
    }
    //遍历队列
    public  void  showQue(){
    
    
        if (isNull()){
    
    
            System.out.println("队列为空");
        }else {
    
    
            for (int i = 0; i < arr.length; i++) {
    
    
                System.out.println(arr[i]);
            }
        }
    }
    //显示队列的头数据
    public int headQue(){
    
    
        if (isNull()){
    
    
            throw  new RuntimeException("队列为空");
        }
        return arr[++front];//比如删除第一个数据front从-1变为0,此时头数据的指针应该指向第二个元素也就是下标为1数据
    }

}

Implementing a queue this way has disadvantages:

队列只能使用一次(数组尺寸是固定的,添加满了就不能添加了
,只是指针发生改变),
不能达到复用的效果

3. Array implements circular queue

insert image description hereImplementation ideas:

  • front points to the first element of the queue, initializes front=0, rear points to the position after the last element of the queue, initializes rear=0, and vacates a space as a convention.

  • When the queue is full (rear+1)%maxSize=front

  • front=rear when the queue is empty

  • Enqueue rear=(rear+1)%maxSize

  • Dequeue front = (front+1)%maxSize

  • Valid data in the queue: (rear + maxSize - front) %maxSize

    假设maxSize=3,实际上只能存储2个元素,初始化front=0,rear=0;
    入队一个元素
           添加:   front=0   arr[rear=0]   rear后移: rear=(rear+1)%maxSize=(0+1)%3=1
           继续添加:front=0   arr[rear=1]   rear后移:  (1+1)%3=2
           此时rear=(rear+1)%maxSize=(2+1)%3=0=front所以队列已经 满了
    出队一个元素
    		 出队:     front=0    front后移:  front = (front+1)%maxSize=(0+1)%3=1;
    		 继续出队:  front=1    front后移:  front = (front+1)%maxSize=(1+1)%3=2;
    		 此时front=(front+1)%maxSize=(2+1)%3=0=rear所以队列已经 空了
    队列中的有效数据:(rear + maxSize - front) %maxSize
          添加两个元素rear=2,删除一个front=1.有效数据为(2+3-1)%3=1   
                          0              2           (0+3-2)%3=1   
                          0              1           (0+3-1)%3=2
                          2              1           (2+3-1)%3=1
                          0              0           (0+3-0)%3=0
    
package Que;

import java.util.Scanner;

/*数组模拟循环队列
* */
public class ArrToCirQue {
    
    
    public static void main(String[] args) {
    
    
        //创建一个尺寸为5的队列
        CirQueue queue = new CirQueue(3);
        Scanner scanner = new Scanner(System.in);
        char key=' ';
        boolean loop=true;
        while (loop){
    
    
            System.out.println("d:显示队列");
            System.out.println("e:退出程序");
            System.out.println("a:添加数据到队列");
            System.out.println("b:从队列取出数据");
            System.out.println("c:查看队列头部数据");
            key=scanner.next().charAt(0); //获取用户输入的第一个字符
            switch (key){
    
    
                case 'a':
                    System.out.println("请输入一个数");
                    int value= scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'b':
                    try{
    
    
                        int res = queue.delQue();
                        System.out.println("去除的数据为:"+res);
                    }catch (Exception e){
    
    
                        System.out.println(e.getMessage());//低下抛出异常,这里捕捉异常信息
                    }
                    break;
                case 'c':
                    try{
    
    
                        int res = queue.headQue();
                        System.out.println("头数据为:"+res);
                    }catch (Exception e){
    
    
                        System.out.println(e.getMessage());//低下抛出异常,这里捕捉异常信息
                    }
                    break;
                case 'd':
                    queue.showQue();
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
    }
}
class CirQueue{
    
    
    int maxSize ;
    int front;
    int rear;
    int[] arr;
    //通过构造方法初始化
    public CirQueue(int maxSize) {
    
    
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }
    //判断队列是否为空
    public  boolean isNull(){
    
    
        //初始化都为0为true
        return front==rear;
    }
    //判断队列是否是满的
    public boolean isFull(){
    
    
        return front==(rear+1)%maxSize;
    }
    //队列中添加数据
    public void  addQueue(int data){
    
    
        //先判断队列是不是满的
        if(isFull()){
    
    
            //抛出运行时异常
            System.out.println("队列已经满了");
        }else {
    
    
            arr[rear]=data;//先放元素再后移
            rear=(rear+1)%maxSize;
        }
    }
    //从队列中删除数据
    public  int delQue(){
    
    
        //首先判断队列是否为空
        if (isNull()){
    
    
            throw new RuntimeException("队列为空");
            //System.out.println("队列为空");
        }else {
    
    
            int value  = arr[front];
            front = (front+1)%maxSize;
            return value;
        }
    }
    //遍历队列
    public  void  showQue(){
    
    
        if (isNull()){
    
    
            System.out.println("队列为空");
        }else {
    
    
            for (int i = front; i < front + (rear + maxSize - front) %maxSize; i++) {
    
    
                System.out.println(arr[i% maxSize]+"下标为"+i% maxSize);
            }
        }
    }
    //显示队列的头数据
    public int headQue(){
    
    
        if (isNull()){
    
    
            throw  new RuntimeException("队列为空");
        }
        return arr[front];
    }
}

Guess you like

Origin blog.csdn.net/qq_45637894/article/details/131029074