1. Sparse array
1.1 what is a sparse array
- Sparse array, first of all, remove the sparse array. It is understood that you, who write the program, have thinning and less hair.
- For example, a chess board can be represented by a binary array. For this chess card (there are only three kinds of data, 0 means no chess pieces, 1 means black chess, and 2 means white chess), we can only extract the positions of black and white chess to form a sparse array.
1.2 application scenarios
- For example, it can be used when there are large quantities and most of them are duplicate values (chess, cards, maps, etc.)
1.3 graphic analysis
- First, create a new array to record how many rows, columns and different values the array has
- Then, the columns, rows and values (the color of the chess pieces) in the element are recorded in a small-scale array, so as to reduce the size of the program.
1.4 code implementation and ideas
2D array to sparse array
Idea:
- The first thing to note is that both rows and columns are designed from scratch.
- Traverse the original binary array and obtain the number sum of valid values [1 (black chess) and 2 (white chess)]
- Then create a sparse array sparsearray[sum + 1][3] according to sum
Note: because the first one-dimensional array of the sparse array needs to save the number of rows, columns and valid values of the original array, the number of one-dimensional arrays of the sparse array is sum+1 - Store the valid data of the original two-dimensional array into a sparse array
(valid data: row, column and value of element [1, 2])
Sparse array to 2D array
Idea:
- First, create the original two-dimensional array according to the first row of the sparse array
- Read the row, column and value of the sparse array from the second row, and assign the value back to the original two-dimensional array
The code includes serialization and deserialization. If not, you can see it Java Basics
code implementation
public class Demo1 { public final static String RESOURCE_PATH = ""; /** * 2D array to sparse array */ private static int[][] arr2Sparse(int[][] chessArr) { // Step 1: total number of valid values obtained int sum = 0; for (int[] row : chessArr) { for (int data : row) { if (data != 0) { sum++; } } } System.out.println("Total valid values obtained:" + sum); // Total valid values obtained: 3 // Step 2: valid data initialization of sparse array int[][] sparseArray = new int[sum + 1][3]; // Initialize valid data for sparse arrays sparseArray[0][0] = 11; sparseArray[0][1] = 11; sparseArray[0][2] = sum; // Traverse the original binary array and put valid pieces (non-0) into sparseArray // i represents row and j represents column int count = 0; // Record the number of effective pieces for (int i = 0; i < chessArr.length; i++) { for (int j = 0; j < chessArr.length; j++) { if (chessArr[i][j] != 0) { count++; sparseArray[count][0] = i; sparseArray[count][1] = j; sparseArray[count][2] = chessArr[i][j]; } } } return sparseArray; } /** * Sparse array to 2D array (restore chessboard) */ private static int[][] sparse2Arr(int[][] sparseArray) { int[][] chessArr = new int[sparseArray[0][0]][sparseArray[0][1]]; // The second line starts the assignment for (int i = 1; i < sparseArray.length; i++) { // Representation: the valid value of each sparse row is copied to the original row and column chessArr[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2]; } return chessArr; } /** * Traversal tool class */ private static void print(int[][] array) { for (int[] row : array) { for (int data : row) { System.out.printf("%d\t", data); } System.out.println(); } } public static void main(String[] args) { // Create an original chess card size of 11 * 11 // 1 black, 2 white, 0 no int[][] chessArr = new int[11][11]; // Drop a few pieces at random chessArr[1][2] = 1; chessArr[3][4] = 2; chessArr[5][7] = 1; // Output original binary array (chess and cards) System.out.println("Output my chessboard:"); // ergodic print(chessArr); System.out.println("------------------------------------2D array to sparse array-----------------------------------"); int[][] sparseArray = arr2Sparse(chessArr); System.out.println("Sparse array:"); print(sparseArray); System.out.println("------------------------------------Sparse array to 2D array(Restore chessboard)-----------------------------------"); // Sparse array to original array row * column int[][] chessArr2 = sparse2Arr(sparseArray); // ergodic System.out.println("Restored 2D array"); print(chessArr2); // =====================The following is serialization, which can be ignored===================== // Sparse serialization sparseSerialize(sparseArray); // Sparse deserialization int[][] arr = (int[][]) sparseDSerialize(); if (arr != null) { System.out.println("Finally, get the class class type" + arr.getClass().getName()); print(arr); } } /** * Serialization tool class */ private static void sparseSerialize(int[][] array) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream(RESOURCE_PATH)); oos.writeObject(array); oos.flush(); } catch (Exception e) { e.getStackTrace(); } finally { try { if (oos != null) { oos.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Serialization tool class */ private static Object sparseDSerialize() { ObjectInputStream ois = null; Object arr; try { ois = new ObjectInputStream(new FileInputStream(RESOURCE_PATH)); arr = ois.readObject(); return arr; } catch (Exception e) { e.getStackTrace(); } finally { try { if (ois != null) { ois.close(); } } catch (Exception e2) { e2.getStackTrace(); } } return null; } }
Output results:
Output my chessboard: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ------------2D array to sparse array------------- Total valid values obtained: 3 Sparse array: 11 11 3 1 2 1 3 4 2 5 7 1 ----------Sparse array to 2D array(Restore chessboard)---------- Restored 2D array 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2. Queue (array simulation)
2.1 basic description of queue
- Queue is a sequential list, which can be implemented by array or linked list
- Follow the principle of first in, first out. First store the data, first take it out, then store it and then take it out
2.2 array simulation queue
Resolution:
- The queue itself has a sequence table. If the array structure is used to store the data of the queue, the declaration of the queue array is as shown in the figure above, where maxSize is the maximum capacity of the queue.
- Because the output and input of the queue are processed from both ends respectively, two variables front and rear are required to record the subscripts at both ends of the queue respectively. The front will change with the data output, while the rear will change with the data input.
2.3 design ideas
Explain the two operations of joining and leaving the queue (preconditions: the initial values of front and rear point to the front of the first number in the queue, that is, front=rear=-1)
When we store data into a queue, it is called addQueue. The processing of addQueue requires two steps:
- First, judge whether the queue is full (rear == maxSize - 1 indicates that the queue is full). If it is full, the data cannot be stored in the queue.
- Then move the tail pointer back: rear + 1 and put the data into the queue.
When we take data out of the queue (out of the queue) as getQueue, the processing of getQueue needs two steps:
- First, judge whether the queue is empty (rear == front indicates that the queue is empty). If it is empty, data cannot be retrieved.
- Then move the header pointer back: front + 1, take the data out of the queue, and finally reset the position of the data to 0.
2.4 code implementation
// Queue entity class public class ArrayQueue { private final int maxSize;// Maximum capacity of the array private int front; // Queue header private int rear; // End of column private final int[] arr; // This array is used to simulate the data stored in the queue // Create queue constructor public ArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[arrMaxSize]; front = -1;// Point to the queue header. The initialized front is the previous position of the queue header rear = -1; // Point to the end of the queue, which means the position of the last data in the queue. The initial value is also the previous position of the queue head } // Determine whether the queue is full public boolean isFull() { return rear == maxSize - 1;// The end of the queue = = the last data of the array indicates that the queue is full } // Determine whether your queue is empty public boolean isEmpty() { return front == rear;// If the head and tail are equal, there is no data } // Add data to queue public void addQueue(int n) { // Determine whether the queue is full if (isFull()) { System.out.println("The queue is full,Unable to add data~~~~"); return; } rear++; // Move rear arr[rear] = n; } // Get queue data (out of queue) public int getQueue() { // Determine whether the queue is empty if (isEmpty()) { // Throw null by exception throw new RuntimeException("The queue is empty, unable to fetch data~~~"); } front++;// front backward int result = arr[front]; // Take out the value of the current queue arr[front] = 0;// Reset the removed position to 0 return result; } // Displays all data for the queue public void showQueue() { // Air judgment if (isEmpty()) { System.out.println("Queue is empty,cannot display data~~~~"); return; } // ergodic for (int i = 0; i < arr.length; i++) { System.out.printf("arr[%d]=%d\n", i, arr[i]); } } // Show header queue instead of fetch public int headQueue() { // Air judgment if (isEmpty()) { // Throw null by exception throw new RuntimeException("The queue is empty, unable to fetch data~~~"); } // display return arr[front + 1];// The reason for adding one here is that at the beginning, initialization points to the previous one of the queue header } }
// Test class public class Demo2 { public static void main(String[] args) { //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("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"); key = scanner.next().charAt(0);//Receive a character switch (key) { case 's': queue.showQueue(); break; case 'a': System.out.println("Output a number"); int value = scanner.nextInt(); queue.addQueue(value); break; case 'g': //Fetch data try { int res = queue.getQueue(); System.out.printf("The extracted data is%d\n", res); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } break; case 'h': //View data of queue header try { int res = queue.headQueue(); System.out.printf("The data in the queue header is%d\n", res); } catch (Exception e) { System.out.println(e.getMessage()); } break; case 'e': //sign out scanner.close(); loop = false; break; default: break; } } System.out.println("Program exit~~"); } }
2.5 problems with this queue
- At present, the designed queue can only be used once (because the array can only be used once), which does not achieve the reuse effect
- Therefore, we need to improve the algorithm of this array into a ring queue (modulus%)
2.6 design idea of ring queue (there are many implementation methods for reference only)
- Front variable adjustment: the initial value of front = 0, which directly points to the first number of queues.
- Adjustment of rear variable: the initial value of rear = 0. Always point to the last position in the queue (the logic of joining the queue here is to join the queue first and then + +)
- The formula to judge whether the queue is full is (rear + 1)% maxsize = = front. Here, we want to make a space available as a convention to judge whether the queue is full. For example, if the array length is 5, it will be judged that it is full by storing 4 data (a space must be wasted, otherwise there is no way to distinguish between empty and full)
- The formula for judging that the queue is empty, rear == front, (if front reaches the position of rear, it means that the queue is finished)
- Number of valid data in the queue (rear + maxsize - front)% maxsize
As for the formula derivation of the fifth point, under normal circumstances, the number of effective data should be rear front, but the subscript of rear may be less than front in the ring queue. Therefore, maxSize is added here to ensure that rear must be greater than front, and then the module is taken to achieve the effect of calculating effective data.
2.7 code implementation
// Ring queue entity class public class CircleArrayQueue { // Maximum capacity of the array private final int maxSize; private final int[] arr; // Front points to the first element of the queue, that is, arr[front] is the first element of the queue private int front; // rear points to the next position of the last element of the queue private int rear; // Create queue constructor public CircleArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[arrMaxSize]; // The default value of front rear is 0, and the declared default value is 0, so there is no need to assign values repeatedly } // Determine whether the queue is full public boolean isFull() { // The ring queue has a vacant space at the end of the queue to judge whether it is full or not return (rear + 1) % maxSize == front; } // Determine whether your queue is empty public boolean isEmpty() { // If the head and tail are equal, there is no data return front == rear; } // Add data to queue public void addQueue(int n) { // Determine whether the queue is full if (isFull()) { System.out.println("The queue is full,Unable to add data~~~~"); return; } // Straight in arr[rear] = n; // When the real moves backward, the subscript out of bounds module (ring) must be considered rear = (rear + 1) % maxSize; } // Get queue data (out of queue) public int getQueue() { // Determine whether the queue is empty if (isEmpty()) { // Throw null by exception throw new RuntimeException("The queue is empty, unable to fetch data~~~"); } // front is the first element pointing to the queue // First save the front value to a temporary variable for returning // Then move back int value = arr[front]; front = (front + 1) % maxSize; return value; } // Displays all data for the queue public void showQueue() { // Air judgment if (isEmpty()) { System.out.println("Queue is empty,cannot display data~~~~"); return; } // Traversal (from beginning to end + number of valid data) for (int i = front; i < front + size(); i++) { System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]); } } // Calculate the number of valid data public int size() { return (rear - front + maxSize) % maxSize; } // Show header queue instead of fetch public int headQueue() { // Air judgment if (isEmpty()) { // Throw null by exception throw new RuntimeException("The queue is empty, unable to fetch data~~~"); } // display return arr[front]; } }
// Test class public class Demo3 { public static void main(String[] args) { //Create a queue CircleArrayQueue queue = new CircleArrayQueue(4);// The valid data is 3 char key = ' '; //Receive user input Scanner scanner = new Scanner(System.in);// boolean loop = true; //Output a menu while (loop) { 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"); key = scanner.next().charAt(0);//Receive a character switch (key) { case 's': queue.showQueue(); break; case 'a': System.out.println("Output a number"); int value = scanner.nextInt(); queue.addQueue(value); break; case 'g': //Fetch data try { int res = queue.getQueue(); System.out.printf("The extracted data is%d\n", res); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } break; case 'h': //View data of queue header try { int res = queue.headQueue(); System.out.printf("The data in the queue header is%d\n", res); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } break; case 'e': //sign out scanner.close(); loop = false; break; default: break; } } System.out.println("Program exit~~"); } }
General catalogue | Next |
---|---|
Data structure (Java) directory | Unfinished to be continued |