Sparse arrays and queues

Posted by liquidmind on Thu, 10 Feb 2022 23:03:41 +0100

3.1 sparse array

3.1.1 first look at a demand

The Gobang program has the functions of saving, exiting and continuing the upper board.

Analyze the problem:
Because many values of two-dimensional array are the default value of 0, many meaningless data = = > sparse array are recorded.

3.1.2 basic introduction

When most elements in an array are 0 or an array with the same value, sparse array can be used to save the array.

The processing method of sparse array is:
(1) How many rows and columns are there in the record array? How many different values are there
(2) Record the rows, columns and values of elements with different values in a small array, so as to reduce the size of the program.

Examples of sparse arrays:

3.1.3 application examples

(1) Use a sparse array to preserve a two-dimensional array similar to the previous one (chessboard, map, etc.)
(2) Save the sparse array and restore it to the original two-dimensional array
(3) Overall thinking analysis

(4) Code implementation

package com.xjs.sparsearray;


/**
 * @Author: Xie Jiasheng
 * @Date: 2022/2/7-02-07-14:09
 * @Version: 1.0
 */
public class SparseArray {
    public static void main(String[] args) {

        //Create original 2D array
        //0 means there are no pieces, 1 means sunspots, and 2 means bluestones
        int[][] chessArray1 = new int[11][11];
        chessArray1[1][2] = 1;
        chessArray1[2][3] = 2;
        // Output the original two-dimensional array
        for (int[] rows : chessArray1) {
            for (int data : rows) {
                System.out.print("\t" + data);
            }
            System.out.println();//Line feed
        }

        // The idea of transforming two-dimensional array into sparse array
        // 1. First traverse the two-dimensional array to get the number of non-0 data
        int sum = 0;
        for (int i = 0; i < chessArray1.length; i++) {
            for (int j = 0; j < chessArray1[i].length; j++) {
                if (chessArray1[i][j] != 0) {
                    sum++;
                }
            }
        }

        // 2. Create the corresponding sparse array
        int[][] sparseArray = new int[sum + 1][3];
        // Assign values to sparse arrays
        sparseArray[0][0] = 11;
        sparseArray[0][1] = 11;
        sparseArray[0][2] = sum;

        // Traverse the two-dimensional array and store non-zero values in sparseArray
        int count = 0; //count is used to record the number of non-zero data
        for (int i = 0; i < chessArray1.length; i++) {
            for (int j = 0; j < chessArray1[i].length; j++) {
                if (chessArray1[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArray1[i][j];
                }
            }
        }

        // Output sparse array form
        System.out.println();
        System.out.println("========Get the sparse array as=======");
        for (int i = 0; i < sparseArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n",sparseArray[i][0],sparseArray[i][1],sparseArray[i][2]);
        }

        //Restore the sparse array -- > to the original two-dimensional array
		/*
		 *  1. First read the first row of the sparse array and create the original two-dimensional array according to the data of the first row, such as chessArray2 = int [11][11] above
			2. Then read the data of the last few rows of the sparse array and assign it to the original two-dimensional array
		 */

        //1. First read the first row of the sparse array and create the original two-dimensional array according to the data of the first row
        int[][] chessArray2 = new int[sparseArray[0][0]][sparseArray[0][1]];

        //2. Read the data of the last few rows of the sparse array and assign it to the original two-dimensional array

        for(int i = 1; i < sparseArray.length; i++) {
        			chessArray2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        		}

        // Output recovered two-dimensional array
        System.out.println();
        System.out.println("======Restored 2D array======");

        for (int[] row : chessArray2) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }


    }
}

3.2 queue

3.2.1 a usage scenario of queue

Bank Queuing cases:

3.2.2 queue introduction

  • Queue is a sequential list, which can be realized by array or linked list.
  • Follow the principle of first in first out. That is, the data stored in the queue first should be taken out first, and the data stored later should be taken out later.
  • Schematic: (use array to simulate queue schematic)

3.2.3 array simulation queue idea

(1) The queue itself has a sequence table. If the structure of the array is used to store the data of the queue, the declaration of the queue array is shown in the figure below, where maxSize is the maximum capacity of the queue.
(2) Because the output and input of the queue are processed from the front and rear ends respectively, two variables front and rear are required to record the subscripts of the front and rear ends of the queue respectively. The front will change with the data output, and the rear will change with the data input, as shown in the figure:

(3) When we store data into the queue, it is called "addQueue". The processing of addQueue needs two steps:
Train of thought analysis:

a. Move the tail pointer back: rear + 1. When front = rear, it indicates that the queue has not added data and is empty.

b. If the tail pointer rear is less than the maximum subscript maxSize - 1 of the queue, the data can be stored in the array element referred to by rear, otherwise the data cannot be stored. rear = maxSize - 1 [queue full]

(4) Code implementation

package com.xjs.queue;

import com.sun.prism.impl.shape.BasicRoundRectRep;

import java.util.Scanner;

/**
 * @Author: Xie Jiasheng
 * @Date: 2022/2/7-02-07-15:48
 * @Version: 1.0
 */
public class ArrayQueueDemo {
    public static void main(String[] args) {

        //Test one
        //Create a queue
        ArrayQueue queue = new ArrayQueue(3);
        char key = ' '; //Receive user input
        Scanner scanner = new Scanner(System.in);//
        boolean loop = true;
        //Output a menu
        while (loop) {
            System.out.println("=============================");
            System.out.println("s(show): Show queue");
            System.out.println("e(exit): Exit program");
            System.out.println("a(add): Add data to queue");
            System.out.println("g(get): Fetch data from queue");
            System.out.println("h(head): View data of queue header");
            System.out.println("=============================");

            System.out.print("Please enter your choice:");
            key = scanner.next().charAt(0);//Receive a character
            switch (key) {
                case 's':
                    queue.showAllQueue();
                    break;
                case 'a':
                    System.out.print("Please enter the data you want to add:");
                    int n = scanner.nextInt();
                    queue.addQueue(n);
                    break;
                case 'g':
                    try {
                        int i = queue.getQueue();
                        System.out.println("The data you take out is:" + i);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    int i = queue.headQueue();
                    System.out.println("The queue header data is:" + i);
                    break;
                case 'e':
                    loop = false;
                    scanner.close();
                    break;
            }

        }
        System.out.println("You quit the program~~~");
    }
}

//Use an array to simulate a queue and write an ArrayQueue class
class ArrayQueue {
    private int maxSize;//Represents the maximum capacity of the array
    private int front;//Queue header
    private int rear;//Queue tail
    private int[] arr;//This array is used to store data and simulate queues

    //Constructor to create a queue
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        front = -1;// Point to the queue head and analyze that front is the previous position pointing to the queue head
        rear = -1;// Point to the end of the queue, and point to the data at the end of the queue (that is, the last data of the queue)
        arr = new int[maxSize];
    }

    //Determine whether the queue is null
    public boolean isEmpty() {
        return front == rear;
    }

    //Determine whether the queue is full
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    //Add data to queue
    public void addQueue(int val) {
        //First determine whether the queue is full
        if (isFull()) {
            System.out.println("The queue is full,No more data can be added...");
            return;
        }
        rear++;//Shift the end of the queue by one bit
        arr[rear] = val;
    }

    //Get the data of the queue and get out of the queue
    public int getQueue() {
        //First judge whether the queue is empty
        if (isEmpty()) {
            throw new RuntimeException("Queue is null,No data is available...");
        }
        front++;
        return arr[front];
    }

    //Displays all data in the queue
    public void showAllQueue() {
        //First determine whether the queue is null
        if (isEmpty()) {
            System.out.println("The queue is empty and there is no data~~~");
            return;
        }
        //Traversal array
        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]= %d\n", i, arr[i]);
        }
    }

    //Display the header data of the queue. Note that the data is not taken out
    public int headQueue() {
        //First determine whether the queue is null
        if (isEmpty()) {
            throw new RuntimeException("The queue is empty and there is no data~~~");
        }
        return arr[front + 1];
    }

}

(5) Problem analysis and optimization
a. At present, the array cannot be reused after being used once, which does not achieve the effect of reuse
b. Use the algorithm to improve this array into a ring queue module

3.2.4 array simulation ring queue

Optimize the simulation queue of the previous array and make full use of the array. Think of the array as a ring. (it can be realized by taking mold)
Analysis description:
(1) When the next index in the tail index is the header index, it indicates that the queue is full, that is, one queue capacity is vacated as a contract. When judging that the queue is full, you should pay attention to (rear + 1)% maxSize == front [queue is full]
(2) rear == front [queue empty]
(3) Schematic diagram of analysis:

(4) Code implementation

package com.xjs.queue;

import java.util.Scanner;

/**
 * @Author: Xie Jiasheng
 * @Date: 2022/2/8-02-08-13:40
 * @Version: 1.0
 */
public class CircleArrayQueueDemo {
    public static void main(String[] args) {

        //Test one
        System.out.println("Test array simulation ring queue case~~~");
        //Create a queue
        CircleArray queue = new CircleArray(4);//Set 4, and the maximum valid data of its queue is 3
        char key = ' '; //Receive user input
        Scanner scanner = new Scanner(System.in);//
        boolean loop = true;
        //Output a menu
        while (loop) {
            System.out.println("=============================");
            System.out.println("s(show): Show queue");
            System.out.println("e(exit): Exit program");
            System.out.println("a(add): Add data to queue");
            System.out.println("g(get): Fetch data from queue");
            System.out.println("h(head): View data of queue header");
            System.out.println("=============================");

            System.out.print("Please enter your choice:");
            key = scanner.next().charAt(0);//Receive a character
            switch (key) {
                case 's':
                    queue.showAllQueue();
                    break;
                case 'a':
                    System.out.print("Please enter the data you want to add:");
                    int n = scanner.nextInt();
                    queue.addQueue(n);
                    break;
                case 'g':
                    try {
                        int i = queue.getQueue();
                        System.out.println("The data you take out is:" + i);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    int i = queue.headQueue();
                    System.out.println("The queue header data is:" + i);
                    break;
                case 'e':
                    loop = false;
                    scanner.close();
                    break;
            }

        }
        System.out.println("You quit the program~~~");

    }
}

class CircleArray {
    private int maxSize; // Represents the maximum capacity of the array
    //Adjust the meaning of the front variable:
    //Front points to the first element of the queue, that is, arr[front] is the first element of the queue
    //Initial value of front = 0
    private int front;
    //Adjust the meaning of the real variable:
    //rear points to the next position of the last element of the queue Because I hope to free up a space as an agreement
    //Initial value of rear = 0
    private int rear;
    private int[] arr; // This data is used to store data and simulate the queue

    public CircleArray(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
    }

    //Determine whether the queue is null
    public boolean isEmpty() {
        return front == rear;
    }

    //Determine whether the queue is full
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    //Add data to queue
    public void addQueue(int val) {
        //First determine whether the queue is full
        if (isFull()) {
            System.out.println("The queue is full,No more data can be added...");
            return;
        }
        //The rear points to the last position of the queue, so data is directly added to the arr[rear]
        arr[rear] = val;
        //When the rear moves backward, take the mold into account
        rear = (rear + 1) % maxSize;
    }

    //Get the data of the queue and get out of the queue
    public int getQueue() {
        //First judge whether the queue is empty
        if (isEmpty()) {
            throw new RuntimeException("Queue is null,No data is available...");
        }
        // Here, we need to analyze that front is the first element pointing to the queue
        // 1. First keep the value corresponding to front to a temporary variable
        // 2. Move the front backward and consider taking the mold
        // 3. Return temporarily saved variables
        //Front is the first element pointing to the queue, but we need to move the front backward after fetching the data
        //If you return arr[front] directly, you have no chance to move the front backward
        //Therefore, an auxiliary variable is needed to save the first element in the queue
        int value;
        // 1. First keep the value corresponding to front to a temporary variable
        value = arr[front];
        // 2. Move the front backward and consider taking the mold
        front = (front + 1) % maxSize;
        // 3. Return temporarily saved variables
        return value;
    }

    //Displays all data in the queue
    public void showAllQueue() {
        //First determine whether the queue is null
        if (isEmpty()) {
            System.out.println("The queue is empty and there is no data~~~");
            return;
        }
        // Idea: start traversing from front, and how many elements are traversed
        //The number of valid data in the queue should be considered
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]= %d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    //Find the number of valid data in the queue
    public int size() {
        // rear = 2
        // front = 1
        // maxSize = 3
        return (rear + maxSize - front) % maxSize;
    }

    //Display the header data of the queue. Note that the data is not taken out
    public int headQueue() {
        //First determine whether the queue is null
        if (isEmpty()) {
            throw new RuntimeException("The queue is empty and there is no data~~~");
        }
        return arr[front];
    }

}

Topics: Algorithm data structure