Chapter 2 sparse arrays and queues

Keywords: Java data structure queue

Chapter 2 sparse arrays and queues

2.1 sparse array

2.1.1 basic introduction

When most elements in an array are 0 or the same value array, sparse array can be used to save the array (compress redundant data)

Representation of sparse array:

  1. How many rows and columns are there in the first row? How many different values are there (relative to redundant values)
  2. The rows, columns and values of elements with different values are recorded in a small-scale array, so as to reduce the size of the program

2.1.2 application cases

The idea of converting two-dimensional array to sparse array:

  1. Traverse the original two-dimensional array to get the number of valid data sum
  2. Build sparse array sparseArr int[sum+1][3] according to sum
  3. Store the valid data of two-dimensional array into sparse array

The idea of converting sparse array to two-dimensional array:

  1. Read the first row of the sparse array and create the original two-dimensional array
  2. Read the data of the last few rows of the sparse array and assign it to the original two-dimensional array
public class SparseArray {
    public static void main(String[] args) {
        //Build the original chessboard array
        int[][] chessArr = new int[11][11];
        chessArr[1][2]=1;
        chessArr[2][3]=2;

        //Print checkerboard array
        for(int[] row : chessArr){
            for(int item : row){
                System.out.printf("%d\t", item);
            }
            System.out.println();
        }

        //Circularly count the number of valid data in the chessboard array
        int sum = 0;
        for(int[] row:chessArr){
            for(int item:row){
                if(item!=0) sum++;
            }
        }

        //Building sparse arrays based on sum
        int[][] sparseArr = new int[sum+1][3];
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = sum;

        //Cycle the chessboard array again and store the valid data in the sparse array
        int cntels = 0;//Statistics of the n th valid data
        for(int i=0;i< chessArr.length;++i){
            for(int j=0;j<chessArr[i].length;++j){
                if(chessArr[i][j]!=0){
                    cntels++;
                    sparseArr[cntels][0] = i;
                    sparseArr[cntels][1] = j;
                    sparseArr[cntels][2] = chessArr[i][j];
                }
            }
        }

        //Print sparse array
        for(int[] row : sparseArr ){
            for(int item : row){
                System.out.printf("%d\t", item);
            }
            System.out.println();
        }

        //Build checkerboard array to be restored
        int[][] newChessArr = new int[sparseArr[0][0]][sparseArr[0][1]];

        //Restore the chessboard array according to the last few rows of data of the sparse matrix
        for(int i=1;i< sparseArr.length;++i){
            newChessArr[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
        }

        //Print restored checkerboard array
        for(int[] row : chessArr){
            for(int item : row){
                System.out.printf("%d\t", item);
            }
            System.out.println();
        }
    }
}

2.2 queue

2.2.1 queue introduction

  • Queue is a sequential list, which can be implemented by array or linked list
  • Follow the principle of first in first out

2.2.2 simulating sequential queues with arrays

Idea: there is a maxSize to indicate the maximum capacity of the queue. front represents the head of the queue (the previous position of the queue head element), and rear represents the tail of the queue (the element at the tail of the queue)

realization:

/**
 * The type Array queue test.
 * @author ybs
 */
public class ArrayQueueTest {
    public static void main(String[] args) {
        int size=0;
        char operation;
        boolean loop = true;
        Scanner in = new Scanner(System.in);
        System.out.print("Enter list length:");
        size = in.nextInt();
        ArrayQueue queue = new ArrayQueue(size);

        while(loop){
            System.out.println("e(exit):Exit program");
            System.out.println("a(add):Add element to queue");
            System.out.println("g(get):Get queue elements");
            System.out.println("l(list):Print queue");
            System.out.println("Please enter an action:");
            operation = in.next().charAt(0);
            switch (operation) {
                case 'a':
                    int element;
                    System.out.print("Enter the element to add:");
                    element = in.nextInt();
                    queue.add(element);
                    break;
                case 'g':
                    try {
                        System.out.println("The extracted elements are:" + queue.getElement());
                    }catch (RuntimeException e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'l':
                    queue.listQueue();
                    break;
                case 'e':
                    in.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("Program exit");

    }
}

class ArrayQueue{
    /**
     * maxSize  Maximum queue length
     * front  Queue head pointer
     * rear  Tail pointer
     * arr  Array stores queue data and simulates queue
     */
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;


    /**
     * Array list constructor
     */
    public ArrayQueue(int maxSize){
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front=-1;
        rear=-1;
    }

    /**
     * Judge whether the list is empty
     */
    private boolean isNull(){
        return front == rear;
    }

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

    /**
     * Add list element
     */
    public void add(int num){
        if(isFull()){
            System.out.println("The team is full and can't join!");
            return ;
        }
        rear++;
        arr[rear]=num;
        System.out.println("Successfully added!");
    }

    /**
     * Take out the team head element
     * @return Team head element
     */
    public int getElement(){
        if (isNull()){
            throw new RuntimeException("Empty list, unable to get element");
        }
        front++;
        return arr[front];
    }

    /**
     * Print queue
     */
    public void listQueue(){
        if (isNull()){
            System.out.println("Empty list");
        }
        for(int i=0;i<=rear;++i){
            System.out.printf("arr[%d]=%d\n",i,arr[i]);
        }
    }

}

Problem analysis: there is a false overflow problem, which can be solved by circular queue

2.2.3 simulating circular queues with arrays

The array is treated as a circular queue by modulo

Idea: front points to the first element of the queue, and rear points to the last element of the queue. The initial values of front and rear are both 0. When the queue is full (rear+1)%maxSize=front is established, when the queue is empty, rear=front is established, and the number of valid data in the circular queue is (rear + maxsize front)% maxsize

realization:

/**
 * The type Circle array queue.
 * @author ybs
 */
public class CircleArrayQueueTest {
    public static void main(String[] args) {
        int size;
        char operation;
        boolean loop = true;
        Scanner in = new Scanner(System.in);
        System.out.print("Enter list length:");
        size = in.nextInt();
        CircleArrayQueue queue = new CircleArrayQueue(size);

        while(loop){
            System.out.println("e(exit):Exit program");
            System.out.println("a(add):Add element to queue");
            System.out.println("g(get):Get queue elements");
            System.out.println("l(list):Print queue");
            System.out.println("Please enter an action:");
            operation = in.next().charAt(0);
            switch (operation) {
                case 'a':
                    int element;
                    System.out.print("Enter the element to add:");
                    element = in.nextInt();
                    queue.add(element);
                    break;
                case 'g':
                    try {
                        System.out.println("The extracted elements are:" + queue.getElement());
                    }catch (RuntimeException e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'l':
                    queue.listQueue();
                    break;
                case 'e':
                    in.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("Program exit");
    }
}

class CircleArrayQueue{
    /**
     * maxSize  Maximum queue length
     * front  Queue head pointer
     * rear  Tail pointer
     * arr  Array stores queue data and simulates queue
     */
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;

    public CircleArrayQueue(int maxSize){
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = 0;
        rear = 0;
    }

    private boolean isNull(){
        return rear == front;
    }

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

    public void add(int num){
        if (isFull()) {
            System.out.println("The queue is full and cannot be inserted");
            return;
        }
        //The rear itself points to the next element at the end of the queue, so assign a value first and then move the pointer
        arr[rear]=num;
        rear = (rear + 1) % maxSize;
        System.out.println("Added successfully");
    }

    public int getElement(){
        if (isNull()){
            throw new RuntimeException("Team full, unable to get");
        }
        //The front itself points to the queue head element, so take it out first and then move the pointer
        int getNum = arr[front];
        front = (front + 1) % maxSize;
        return getNum;
    }

    public void listQueue(){
        if(isNull()){
            System.out.println("The queue is empty and cannot be traversed");
            return;
        }
        //At this time, it is impossible to traverse according to the queue length. Use the number of traversals from front to back to solve the problem
        for (int i = front; i < front + elementsSize(); i++) {
            System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
        }
    }

    private int elementsSize(){
        return (rear+maxSize-front)%maxSize;
    }
}

Posted by Mortier on Sat, 04 Dec 2021 19:52:55 -0800