Deadly data structure and algorithm-queue (JAVA)

1. Basic concepts

Queue (FIFIO): A special linear table that conforms to the first-in-first-out principle, that is, the elements that enter the queue first must be taken out first, and then the elements stored in the queue must be taken out.
End of line: the end that allows the insertion of elements. (Front end of the array)
Head of the line: Allows deleting one end of the element. (The back end of the array)

2. Array simulation queue

The input and output of the queue are related to the two ends of the queue, so we set two variables to record the front and end of the queue. The front (front end) is the end where the element is taken out, and the rear (back end) is the end where the element is inserted.

1. Simulation diagram

2. Idea analysis

  1. First, the simulated array needs to be initialized. First obtain the size of the array, that is, the length of the queue, create an array, set two variables front and rear to represent the front end (outgoing queue) and back end (incoming queue) of the queue respectively. front points to the previous element of the first element of the queue, and rear points to the last element of the queue.
  2. Determine whether the queue is empty: When leaving the queue, you need to move the front one space back, and then take out the elements. When entering the queue, you need to insert the element, and then move the rear backward. When front and rear are equal, that is, when front==rear, it means that front does not need to move back to the end of the queue, so the queue is empty at this time.
  3. Determine whether the queue is full: when the rear variable points to the last position of the array, that is, the queue can no longer insert elements, so the queue is full at this time.
  4. To add data to the queue, first determine whether the queue is full, and then join. If it is full, it cannot be inserted. If it is not full, move the rear one space back, and then assign the inserted data to the rear position of the array.
  5. Out of the queue: First, judge whether the queue is empty, and enter. If it is full, no element can come out; if it is not empty, move the front one space back, and then take out the data at the front position in the array.
  6. Display the head data of the queue: Because front points to the previous position of the head of the queue, the element at the position of the array [front+1] is directly taken out is the head data of the queue at this time.

3. Code implementation

class ArrayQueue {
    
    
    private int maxSize; //表示数组的最大容量
    private int front; //队列头-前端
    private int rear; //队列尾-后端
    private int[] arr; //该数组用于存放数据,实现模拟队列

    //创建数组队列的构造器
    public ArrayQueue(int arrMaxSize) {
    
    
        maxSize = arrMaxSize;
        arr = new int[maxSize];  //为数组指定大小
        //front和rear的初始值都等于-1
        front = -1; //指向队列头部,分析出front是指向队列头的前一个位置
        rear = -1; //指向队列尾,指向队列尾的数据(即队列的最后一个数据)
    }

    //判断队列是否满,当rear的值指向数组的最后一个位置时,说明数组的最后一个位置有数据了,即队列满。
    public boolean isFull() {
    
    
        return rear == maxSize - 1;
    }

    //判断队列是否为空,当front和rear的值相等时,队列为空
    public boolean isEmpty(){
    
    
        return front == rear;
    }

    //添加数据到队列
    public void addQueue(int n) {
    
    
        //判断队列是否满
        if(isFull()){
    
    
            System.out.println("队列满,不允许加入数据!!");
        }
        rear++; //让rear 后移
        arr[rear] = n; //把要插入的数据赋值给arr[rear]
    }

    //获取队列的数据,即出队列。即让队列中最先进去的元素出队列
    public int getQueue() {
    
    
        //判断队列是否空
        if(isEmpty()){
    
    
            //通过抛出异常
            throw new RuntimeException( "队列空,不能取数据" );
        }
        front++; //front后移
        return arr[front];
    }

    //显示队列的所有数据
    public void showQueue(){
    
    
        //判断队列是否为空
        if(isEmpty()){
    
    
            System.out.println("此时队列为空,没有数据");
            return;
        }
        //遍历,打印队列
        for (int i = 0; i < arr.length; i++) {
    
    
            System.out.printf( "arr[%d]=%d\n", i, arr[i] );
        }
    }

    //显示队列的头数据,注意不是取出数据
    public int headQueue (){
    
    
        //判断
        if(isEmpty()){
    
    
            throw new RuntimeException( "队列空的,没有数据!" );
        }
        return arr[front+1]; //此处是取出队头数据,不是出队列。所以不需要移动控制出队列的变量front
    }
}

4. Existing problems

The array can only be used once, and the utilization rate is low.
Optimization: Change the array one-way queue to a circular queue.

3. Array simulation circular queue

1. Realization: Treat the array as a ring by modulo.

2. Schematic diagram:

3. Ideas:

  1. front: now points to the first element of the queue. The initial value of front is 0.
  2. rear: At this point, it points to the position after the last element of the queue. Use the vacant position as a convention. The
    initial value of rear is 0.
  3. The queue is full: (rear+1)% maxSize == front.
  4. Queue empty: rear == front
  5. The number of valid data in the queue: (rear + maxSize-front)% maxSize.

4. Code Implementation

class CircleArray {
    
    
    private int maxSize; //表示数组的最大容量
    //front 变量含义做一个调整:front 就指向队列的第一个元素,也就是arr[front]
    //front 的初始值=0
    private int front; //队列头
    //rear 变量的含义做调整: rear 指向队列的最后一个元素的后一个位置,因为希望空出一个位置
    //rear 的初始值=0
    private int rear; //队列尾
    private int[] arr; //该数组用于存放数据,模拟队列

    //创建队列的构造器
    public CircleArray(int arrMaxSize) {
    
    
        maxSize = arrMaxSize;
        arr = new int[maxSize];
    }

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

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

    //添加数据到队列
    public void addQueue(int n) {
    
    
        //判断队列是否满
        if(isFull()){
    
    
            throw new RuntimeException( "队列满,不能加入数据" );
        }
        arr[rear] = n;
        //将rear 后移,此处必须考虑取膜
        rear = (rear + 1) % maxSize;
    }

    //获取队列的数据,出队列。
    public int getQueue() {
    
    
        //判断队列是否空
        if(isEmpty()){
    
    
            //通过抛出异常
            throw new RuntimeException( "队列空,不能取数据" );
        }
        //front 是指向队列的第一个元素
        //1. 先把front 对应的值保存到一个临时变量
        int value = arr[front];
        //2. 将front后移。
        front = (front + 1) % maxSize;
        //3. 将临时保存的变量返回
        return value;
    }

    //显示队列的所有数据
    public void showQueue(){
    
    
        //遍历
        if(isEmpty()){
    
    
            System.out.println("队列空的,没有数据");
            return;
        }
        // 从front开始遍历,遍历多少个元素
        //
        for (int i = front; i < front + size(); i++) {
    
    
            System.out.printf( "arr[%d]=%d\n", i % maxSize, arr[i % maxSize] );
        }
    }

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

    //显示队列的头数据,注意不是取出数据
    public int headQueue (){
    
    
        //判断
        if(isEmpty()){
    
    
            throw new RuntimeException( "队列空的,没有数据!" );
        }
        return arr[front];
    }
}


Summary: This article uses an array to simulate the queue, including the description of the basic operations such as adding, deleting, and code implementation of the queue. Realized the basic one-way queue of array simulation and the use of array to simulate circular queue.

Guess you like

Origin blog.csdn.net/qq_41497756/article/details/108668655
Recommended