JAVA data structure-2. Implementation of ordinary queues and circular queues and analysis of the use of JAVA Queue

Data structure and algorithm

2. Queue

​ Queue is an ordered list, which can be implemented with an array or a linked list.

​ Follow the principle of first in, first out.

Insert picture description here

Implementation ideas (ordinary queue)

  1. ​ When using the structure of an array to implement a queue, create a class that contains an array object queue, and at the same time, maxSize is required to indicate the maximum capacity of the queue;
  2. Because the input and output of the queue are processed separately from the front and back ends, two variables front and rear are required to record the subscripts of the front and back ends of the queue respectively. Front will change with data output, and rear will change with data input;
    1. Among them, front points to the previous position of the first object in the queue .
    2. rear points to the end of the queue.
  3. The method addQueue in the writing class indicates that the queue is added:
    1. Move the tail pointer rear backward: rear+1; when front==rear (the queue is empty).
    2. If the moved tail pointer is less than the maximum subscript maxSize-1 of the queue (the subscript starts from 0), the data is stored in the array element pointed to by the rear, otherwise the data cannot be stored (rear == maxSeize-1, the queue is full )
  4. The method removeQueue in the writing class means to remove the queue:
    1. When the queue is not empty, move the head pointer front by one position to find the first number in the queue.

Code implementation (normal queue)

public class ArrayQueue {
    
    
    public  static void main(String args[]){
    
    
    }
}

class ArrayQueueClass{
    
    
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;
    public ArrayQueueClass(int arrMaxSize){
    
    
        this.maxSize = arrMaxSize;
        front = -1;
        rear = -1;
        arr = new int[arrMaxSize];
    }

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

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

    public void addQueue(int data){
    
    
        if(isFull()){
    
    
            throw new RuntimeException("队列已经满了~");
        }
        rear++;
        arr[rear] = data;
    }

    public int removeQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空,无法取数据");
        }
        front++;
        return arr[front];
    }
    public void showQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        for (int i = front+1; i <= rear ; i++) {
    
    
            System.out.printf("%d\t",arr[i]);
        }
        System.out.println();
    }

    public int check(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }

        return arr[front+1];
    }

}

Problem: The pointer keeps increasing, and the array cannot be used once it is used, and the reuse effect is not achieved.

Solution: Change the array to a circular array and use modulo to achieve

Implementation ideas (circular queue)

  1. The meaning of the front variable is adjusted, front points to the first element of the queue, arr[front] is the first element of the queue, and the initial value of front is 0
  2. The content of the rear variable is adjusted, rear points to the last position of the last element of the queue, because it is hoped that a space will be left as a convention. At this time, the maximum usable capacity of the queue is maxSize-1, and the initial value of rear is 0;
  3. When the queue is full, the condition is (rear+1)%maxSize == front
  4. When the queue is empty, rear == front
  5. The number of valid data in the queue is (rear+maxSize -frotn)%maxSize

Code implementation (circular queue)

public class CircleArrayQueueDemo {
    
    
    public  static void main(String args[]){
    
    
        CricleArrayQueue queue = new CricleArrayQueue(4);   //此时可以用队列为3
        queue.addQueue(0);
        queue.showQueue();
        queue.addQueue(1);
        queue.showQueue();
        queue.addQueue(2);
        queue.showQueue();
//        queue.addQueue(3); //java.lang.RuntimeException: 队列已经满了~  front==0  rear==3

        System.out.println(queue.removeQueue());
        queue.showQueue();
        System.out.println(queue.removeQueue());
        queue.showQueue();
        System.out.println(queue.removeQueue());
        System.out.println();
//        queue.showQueue();//java.lang.RuntimeException: 队列为空  front == rear ==3

        queue.addQueue(4);  //front ==3  rear ==0
        queue.showQueue();
        queue.addQueue(5); //front ==3  rear ==1

        System.out.println(queue.removeQueue());//front ==0  rear ==1
        System.out.println(queue.removeQueue());//front ==1  rear ==1

    }
}
class CricleArrayQueue{
    
    
    private int maxSize;
    public int front;
    public int rear;
    private int[] arr;
    public CricleArrayQueue(int arrMaxSize){
    
    
        this.maxSize = arrMaxSize;
        front = 0;  //front表示指向第一个元素 取元素时先取再+1
        rear = 0;   //rear表示指向最后一个元素的后一个位置  加元素时先加元素在+1
        arr = new int[arrMaxSize];  //设置队列最大长度,此时保留一个位置作为队列满的判断,因此最大可用数量为maxSize-1
    }
    public boolean isEmpty(){
    
    
        if(front == rear){
    
    
            return true;
        }
        return false;
    }

    public boolean isFull(){
    
    
        if((rear+1)%maxSize == front){
    
    
            return true;
        }
        return false;
    }
    public void addQueue(int data){
    
    
        if(isFull()){
    
    
            throw new RuntimeException("队列已经满了~");
        }
        arr[rear] = data;
        rear = (rear+1)%maxSize;
    }
    public int removeQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空,无法取数据");
        }
        int value = arr[front];
        front = (front+1)%maxSize;
        return value;
    }
    public void showQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        for (int i = front; i < front+ (rear - front + maxSize)%maxSize; i++) {
    
    
            System.out.printf("%d\tarr[%d]",i%maxSize,arr[i%maxSize]);
            System.out.println();
        }
        System.out.println();
    }
    public int check(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        return arr[front];
    }

}

The queue class Queue in JAVA

In the advanced data types of Java, the LinkedList class implements the Queue interface, so we can use LinkedList as a Queue.
LinkedList will supplement the source code analysis in the chapter on doubly linked list data structure.

public class javaQueue {
    
    
    public  static void main(String args[]){
    
    
        //add()和remove()方法在失败的时候会抛出异常(不推荐)
        Queue<String> queue = new LinkedList<String>();
        //添加元素
        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        queue.offer("d");
        queue.offer("e");
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("poll="+queue.poll()); //返回第一个元素,并在队列中删除
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("element="+queue.element()); //返回第一个元素
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("peek="+queue.peek()); //返回第一个元素
        for(String q : queue){
    
    
            System.out.println(q);
        }
    }
}

The difference between offer and add:

  • Some queues have size limits, so if you want to add a new item to a full queue, the extra item will be rejected.
  • At this time, the new offer method can work. It does not throw an unchecked exception for calling the add() method, but just gets the false returned by offer().
    The difference between poll and remove:
  • Both remove() and poll() methods remove the first element from the queue. The behavior of remove() is similar to the version of the Collection interface, but the new poll() method does not throw an exception when called with an empty collection, but returns null. Therefore, the new method is more suitable for situations prone to abnormal conditions.
    The difference between peek and element:
  • element() and peek() are used to query elements at the head of the queue. Similar to the remove() method, when the queue is empty, element() throws an exception, and peek() returns null.

Guess you like

Origin blog.csdn.net/weixin_44634197/article/details/108308221