JAVA algorithm
This semester, the teacher handed in the algorithm and sorted out some of the most commonly used algorithms. In fact, the most important thing is the algorithm idea
There are many algorithmic ideas. There are 8 commonly used algorithmic ideas recognized in the industry, namely enumeration, recursion, recursion, divide and conquer, greed, heuristics, dynamic iteration and simulation. Of course, the eight categories are only a general division, which is a problem of "different people see different people, and wise people see different wisdom"
1. Quick sort algorithm
principle
Let the array to be sorted be A[0]... A[N-1]. First, arbitrarily select a data. Usually, the first number of the array is selected as the key data, and then put all numbers smaller than it to its left and all numbers larger than it to its right. This process is called a quick sorting. It is worth noting that quick sorting is not a stable sorting algorithm, that is, the relative positions of multiple identical values may change at the end of the algorithm.
The quick sort algorithm is:
- Set two variables, i and j, at the beginning of sorting: i=0, j=N-1;
- Take the first array element as the key data and assign it to key, that is, key=A[0];
- Start the forward search from j, that is, start the forward search from the back (j –), find the first value A[j] less than the key, and exchange the values of A[j] and A[i];
- Start the backward search from I, that is, start the backward search from the front (I + +), find the first A[i] greater than the key, and exchange the values of A[i] and A[j];
- Repeat steps 3 and 4 until i==j;
- In steps 3 and 4, no qualified value is found, that is, when a [J] in 3 is not less than key and a [i] in 4 is not greater than key, change the values of J and I so that j=j-1 and i=i+1 until it is found. Find the qualified value, and the position of I and j pointers remains unchanged during exchange. In addition, the process of i== j must be exactly when I + or J - is completed, and the cycle ends
Sorting demonstration
Suppose the initial sequence {xi} is: 5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8.
At this time, ref=5, i=1, j=11. Look back and forward. The first number smaller than 5 is x8=2, so the sequence is: 23 7 6 4 1 0 5 9 10 8 |
---|
At this time, i=1 and j=8. Look from front to back. The first number greater than 5 is x3=7, so the sequence is: 23 5 6 4 1 0 7 9 10 8 |
At this time, i=3, j=8, look forward from the 8th bit, and the first number smaller than 5 is x7=0, so: 23 0 6 4 1 5 7 9 10 8 |
At this time, i=3, j=7, look back from the third place, and the first number greater than 5 is x4=6, so: 23 0 5 4 1 6 7 9 10 8 |
At this time, i=4, j=7, look forward from the 7th position, and the first number smaller than 5 is x6=1, so: 23 0 1 4 5 6 7 9 10 8 |
At this time, i=4, j=6, look back from the fourth place, and there is no number greater than 5 until the sixth place. At this time, i=j=6, ref becomes a dividing line. The previous numbers are smaller than it, and the subsequent numbers are larger than it. The same method can be used to sort the front and rear scores |
Code display
package test1; /** * @author Xiao Xu * * 2021 October 30 */ public class First { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("hello,world!"); int[] a =new int[]{100,44,66,88,33,11,44,2}; System.out.println("The data before sorting is:"); print(a); System.out.println("The sorted results are:"); sort(a,0,a.length-1); print(a); } public static void print(int[] b){ for(int i = 0;i < b.length;i++){ System.out.println(b[i]); } System.out.println(""); } //Sorting method static void sort(int[] a,int low,int high){ if(low>=high) return;// If low is less than high, return directly if((high-low)==1){//If there are only two numbers, compare them directly if(a[0]>a[1]) swap(a,0,1); return; } int pivot = a[low];//Take the first number as the sentry int left = low + 1;//Start the exchange step by step. Because the sentry is the first element, start the second number and compare it with the rightmost one int right = high; while(left < right){ while(left < right && left <= high){//If left is less than right, cycle 33 100,40,60,87,34,11,56,0 all the time if (a[left]>pivot) //left =1 right=7 break; left++;//The left subscript goes a little to the right } //Start on the right while(left <= right&& right > low){//If left is greater than right, cycle all the time if(a[right]<=pivot) break; right--;//The right subscript goes a little to the left } if(left < right)//If not, exchange numbers swap(a,right,left); } swap(a,low,right);//Swap sentinels for the next quick sort sort(a,low,right); sort(a,right+1,high); } private static void swap(int[] array,int i,int j){ int temp; temp=array[i]; array[i]=array[j]; array[j]=temp; } }
The result is
2. Direct sorting algorithm
principle
Straight select sorting is also a simple sorting method. Its basic idea is: select the minimum value from R[0]R[n-1] for the first time, exchange with R[0], select the minimum value from R[1]R[n-1] for the second time, exchange with R[1], select the minimum value from R[i-1] ~ R[n-1], exchange with R[i-1], and select the minimum value from R[n-2] ~ R[n-1] for the nth time, Exchange with R[n-2] for a total of n-1 times to obtain an ordered sequence arranged from small to large according to the sorting code.
demonstration
demonstration
For example, given n=8 and the sorting code of 8 elements in array R is (8,3,2,1,7,4,6,5), the direct sorting process is as follows
Because the encyclopedia is inconvenient to draw associated arrows, it is represented by n – n:
Initial state [8 3 2 1 7 4 6 5] 8 – 1 |
---|
First time [1 3 2 8 7 4 6 5] 3 – 2 |
Second [1 2 3 8 7 4 6 5] 3 – 3 |
Third time [1 2 3 8 7 4 6 5] 8 – 4 |
Fourth [1 2 3 4 7 8 6 5] 7 – 5 |
The fifth time [1 2 3 4 5 8 6 7] 8 – 6 |
Sixth [1 2 3 4 5 6 8 7] 8 – 7 |
The seventh [1 2 3 4 5 6 7 8] sorting is completed |
Code demonstration
package test1; import java.util.*; /** * @author Xiao Xu * * 2021 October 30 */ public class Sort { public static void main(String[] args) { int array[] = new int[20];//Defines the size of the array array = new int[] { 5, 3, 7, 9, 23, 42, 12, 1 }; for (int i = 0; i < array.length; i++) { for (int j = i + 1; j < array.length; j++) { if (array[i] > array[j]) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } System.out.println(Arrays.toString(array));// Output the contents sorted after each cycle } System.out.println(Arrays.toString(array));// Output the last sorting result } }
result
3. Insert sort
The basic idea of insert sort is to insert a record to be sorted into an appropriate position in the previously sorted file according to its key value at each step until all records are inserted.
-
Start sorting from the ordered sequence and the unordered sequence {a2,a3,..., an};
-
When processing the ith element (i=2,3,..., n), the sequence {a1,a2,..., ai-1} is ordered, while the sequence {ai,ai+1,..., an} is disordered. Compare ai with ai-1, a, i-2,..., a1, find out the appropriate position and insert ai;
-
Repeat the second step for n-i times of insertion, and the sequence is all in order.
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class InsertionSorting { public static void main(String[] s) { int[] arr = {1,2,3,0}; System.out.println("Before sorting:"+Arrays.toString(arr)); insertSort(arr,0,arr.length); System.out.println("After sorting:"+Arrays.toString(arr)); } public static void insertSort(int[] object,int low,int high) { //Think of the first value as an ordered sequence for(int i = 1;i < high;i++) { if(object[i] < object[i-1]) { int temp = object[i];//Value to be compared int j = i-1; for(;j >= low&&object[j] > temp;j--) { object[j+1] = object[j]; } //Get j last position after comparison object[j+1] = temp; } } } }
result
Before sorting: [1, 2, 3, 0]
After sorting: [0, 1, 2, 3]
4. Sort by half insertion
binary insertion sort is an improvement on the insertion sort algorithm. In the process of sorting algorithm, elements are continuously inserted into the previously ordered sequence. Since the first half is a sequence of numbers arranged in order, we don't need to find the insertion points in order. We can use the method of half search to speed up the speed of finding the insertion points
example
In the process of inserting a new element into the ordered array, when looking for the insertion point, set the first element of the area to be inserted to a[low],
If the last element is set to a[high], the element to be inserted will be compared with a[m], where m=(low+high)/2. If it is smaller than the reference element, select a[low] to a[m-1] as the new insertion area (i.e. high=m-1). Otherwise, select a[m+1] to a[high] as the new insertion area (i.e. low=m+1). In this way, until low < = high is not true, that is, all elements after this position will be moved back one bit, And insert the new element into a[high+1]
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class SplitInsertionSort { public static void main(String[] args){ // Array to be sorted int[] array = { 1, 0, 2, 5, 3, 4, 9, 8, 10, 6, 7}; System.out.println("Before sorting in half:"+Arrays.toString(array)); binaryInsertSort(array); // Displays the sorted results. System.out.println("After sorting in half"+Arrays.toString(array)); } // Binary Insertion Sort method private static void binaryInsertSort(int[] array){ for(int i = 1; i < array.length; i++){ int temp = array[i]; int low = 0; int high = i - 1; while(low <= high){ int mid = (low + high) / 2; if(temp < array[mid]){ high = mid - 1; }else{ low = mid + 1; } } for(int j = i; j >= low + 1; j--){ array[j] = array[j - 1]; } array[low] = temp; } } }
result
Before half sort: [1, 0, 2, 5, 3, 4, 9, 8, 10, 6, 7]
Sort in half [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
5. Bubble sorting
Bubble Sort repeatedly visits the element column to be sorted, compares two adjacent elements in turn, and exchanges them if the order (e.g. from large to small and from Z to A) is wrong. The work of visiting elements is repeated until no adjacent elements need to be exchanged, that is, the element column has been sorted.
The name of this algorithm comes from the fact that the smaller elements will slowly "float" to the top of the sequence (in ascending or descending order) through exchange, just as the bubbles of carbon dioxide in carbonated drinks will eventually float to the top, so it is called "bubble sorting".
example
- Compare adjacent elements. If the first one is bigger than the second, exchange them.
- Do the same for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end. At this point, the last element should be the largest number
- Repeat the above steps for all elements except the last one
- Continue to repeat the above steps for fewer and fewer elements at a time until no pair of numbers need to be compared
Non optimized version
code
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class BubbleSort { public static void bubbleSort(int arr[]) { for(int i = 0 ; i < arr.length-1 ; i++) { for(int j = 0 ; j < arr.length-1-i ; j++) { if(arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } public static void main(String[] args) { // TODO Auto-generated method stub int [] arr = {10,20,3,0,40,52,3,4}; System.out.println("Before bubble sorting:"+Arrays.toString(arr)); bubbleSort(arr); System.out.println("After bubble sorting"+Arrays.toString(arr)); } }
result
Before bubble sorting: [10, 20, 3, 0, 40, 52, 3, 4]
After bubble sorting [0, 3, 3, 4, 10, 20, 40, 52]
Optimized version
After the data sequence is arranged, the bubbling algorithm will continue to conduct the next round of comparison until arr.length-1 times. The subsequent comparison is meaningless.
Scheme:
Set the flag bit flag. If an exchange occurs, set the flag to true; Set to false if there is no exchange.
In this way, if the flag is still false after a round of comparison, that is, there is no exchange in this round, it indicates that the data sequence has been arranged and there is no need to continue.
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class BubbleSort { public static void BubbleSort1(int [] arr){ int temp;//Temporary variable boolean flag;//Flag whether to exchange for(int i=0; i<arr.length-1; i++){ //Indicates the number of times, a total of arr.length-1 times. / / the flag bit must be set to false each time to judge whether the subsequent elements have been exchanged flag = false; for(int j=arr.length-1; j>i; j--){ //Select the maximum value of this sort and move back if(arr[j] < arr[j-1]){ temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; flag = true; //flag is set to true whenever there is an exchange } } // Judge whether the flag bit is false. If it is false, it means that the following elements are in order. return directly if(!flag) break ;} } public static void main(String[] args) { // TODO Auto-generated method stub int [] arr = {10,20,3,0,40,52,3,4}; System.out.println("Before bubble sorting:"+Arrays.toString(arr)); BubbleSort1(arr); System.out.println("After bubble sorting"+Arrays.toString(arr)); } }
result
Before bubble sorting: [10, 20, 3, 0, 40, 52, 3, 4]
After bubble sorting [0, 3, 3, 4, 10, 20, 40, 52]
7. Hill sort
Shell's sort is a kind of insertion sort, also known as "narrowing increment sort". It is a more efficient improved version of direct insertion sort algorithm. Hill sorting is an unstable sorting algorithm.
Hill sort is to group records by certain increment of subscript, and sort each group by direct insertion sort algorithm; As the increment decreases, each group contains more and more keywords. When the increment decreases to 1, the whole file is just divided into one group, and the algorithm terminates.
Generally, half of the sequence is taken as the increment for the first time, and then halved each time until the increment is 1.
The sorting process of shell sorting for a given instance
Suppose there are 10 records in the file to be sorted, and their keywords are:
49,38,65,97,76,13,27,49,55,04.
The values of increment sequence are: 5, 2 and 1
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class ShellSort { public static void main(String[] args){ int[] array={49,38,65,97,76,13,27,49,78,34,12,64,1}; System.out.println("Before sorting"+Arrays.toString(array)); //Shell Sort int gap = array.length; while (true) { gap /= 2; //The increment is halved each time for (int i = 0; i < gap; i++) { for (int j = i + gap; j < array.length; j += gap) {//This loop is actually an insertion sort int k = j - gap; while (k >= 0 && array[k] > array[k+gap]) { int temp = array[k]; array[k] = array[k+gap]; array[k + gap] = temp; k -= gap; } } } if (gap == 1) break; } System.out.println(); System.out.println("After sorting"+Arrays.toString(array)); } }
result
Before sorting [49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1]
After sorting [1, 12, 13, 27, 34, 38, 49, 49, 64, 65, 76, 78, 97]
8. Merge and sort
Recursive merge sort
Merge sort is an effective sort algorithm based on merge operation. The algorithm is a very typical application of Divide and Conquer.
The ordered subsequences are combined to obtain a completely ordered sequence; That is, each subsequence is ordered first, and then the subsequence segments are ordered. If two ordered tables are merged into one, it is called 2-way merging
Merge, also known as merge algorithm, refers to the operation of merging two sorted sequences into one sequence
If there is a sequence {6202100301, 38, 8, 1}
Initial status: [6] [202] [100] [301] [38] [8] [1] comparison times
i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3
i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4
i=3 [ 1 6 8 38 100 202 301 ] 4
Total: 11 codes
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class MergeSort { //test public static void main(String[] args) { Integer[] I = {5,3,1,4,2,10,6,7}; System.out.println("Before sorting:"+Arrays.toString(I)); sort(I); System.out.println("After sorting:"+Arrays.toString(I)); } //Implement merge operation public static void merge(Comparable[] a, int lo, int mid, int hi){ //Define three pointers int p1= lo; //p1 points to the first element of the left subgroup int p2= mid+1; //p2 points to the first element of the right subgroup int i = lo; //i points to the first element of the auxiliary array //Define auxiliary array Comparable[] aux = new Comparable[a.length]; //Realize merging while(p1<=mid || p2<=hi) { if (p1 > mid) aux[i++] = a[p2++]; else if (p2 > hi) aux[i++] = a[p1++]; else if (a[p1].compareTo(a[p2]) < 0) aux[i++] = a[p1++]; else aux[i++] = a[p2++]; } //Copy the sorted aux array to the original array a, so that the corresponding elements in a are ordered for (int k = lo; k <= hi; k++) { a[k]=aux[k]; } } public static void sort(Comparable[] a){ sort(a,0,a.length-1); } public static void sort(Comparable[] a, int lo, int hi){ if (hi<=lo) return; //Divide into two groups int mid = lo+(hi-lo)/2; //Sort by recursion sort(a,lo,mid); sort(a,(mid+1),hi); merge(a,lo,mid,hi); } }
result
Before sorting: [5, 3, 1, 4, 2, 10, 6, 7]
After sorting: [1, 2, 3, 4, 5, 6, 7, 10]
Non recursive merge sort
The division function Merge for non recursive Merge sorting is the same as that for recursive Merge sorting, but a more ingenious method is used to replace the recursive process. The specific process is annotated in the code. The code is as follows:
package test1; import java.util.Arrays; /** * Non recursive merge sort */ /** * @author Xiao Xu * * 2021 October 30 */ public class UnMargeSort { //Partition function, sort to a certain extent, can not be arranged side by side. Recursive call is required to complete merging sort, which is equivalent to dividing and ruling the problem public static void Merge(int []dsi,int []src,int left ,int m, int right) { int i = left, j = m+1; int k = left; while(i<=m && j<=right) { dsi[k++] = src[i] < src[j]? src[i++]:src[j++]; } while(i<=m) { dsi[k++] = src[i++]; } while(j<=right) { dsi[k++] = src[j++]; } } /** * Non recursive merge sort * @param dis Sorted array * @param src Array of source data * @param s Partition interval parameter, which means that s data in this round are arranged together * @param n Subscript value of the last element */ public static void NiceMergePass(int []dis,int []src,int s,int n) // n => index; { System.out.printf("s = %d \n",s); int i = 0; for(i = 0;i+2*s -1 <= n;i = i+2*s) { // i <= n -2*s+1 Merge(dis,src,i,i+s-1,i+2*s-1); System.out.printf("left: %d m: %d right: %d \n",i,i+s-1,i+2*s-1); } if(n >= i+s) { //If the subscript value of the last element is n > = I + s, it means that there are still numbers not divided // We directly pass parameters to the parameter list of the Merge() function to change the division range to ensure that each element is divided Merge(dis,src,i,i+s-1,n); System.out.printf("left: %d m: %d right: %d \n",i,i+s-1,n); } else { //If the subscript value of the last element is n < I + s, it means that the division range exceeds the number of elements, // The reason for this is the operation of expanding the division range such as s+=s in the NiceMergeSort function below //At this time, we only need to put the undivided elements before subscript n into the dis [] array for(int j = i;j<=n;++j) { dis[j] = src[j]; } } } //Recursive merge sorting is implemented, in which ar [] and br [] pass parameters to each other after each merge to prevent the loss of elements that have not been divided public static void NiceMergeSort(int []ar) { int []br = new int[ar.length]; int n = ar.length -1; //n is the subscript value of the last element int s = 1; //The first round s is 1 s, which is used to plan a group of several elements, and then divide the function Merge() while(s < n) { NiceMergePass(br,ar,s,n); System.out.println(Arrays.toString(br)); s+=s; // S in the second round is 2 / / s in the fourth round is 8 / / s < < = 1. You can also operate; NiceMergePass(ar,br,s,n); System.out.println(Arrays.toString(ar)); s+=s; // S in the third round is 4 / / s in the fifth round is 16 / / s < < = 1. You can also operate } } public static void main(String[] args) { int []ar = {23,54,34,56,92,12,65}; System.out.println("Original book:"+Arrays.toString(ar)); NiceMergeSort(ar); System.out.println("Recursive merge sort:"+Arrays.toString(ar)); } }
9. Heap sorting
Heap sort is a sort algorithm designed by using heap data structure. Heap is a structure similar to a complete binary tree and satisfies the nature of heap: that is, the key value or index of a child node is always less than (or greater than) its parent node
principle
In the data structure of the heap, the maximum value in the heap is always located at the root node (if the heap is used in the priority queue, the minimum value in the heap is located at the root node). The following operations are defined in the heap:
- Max heap adjustment: adjust the end terminal node of the heap so that the child node is always smaller than the parent node
- Build Max Heap: reorder all data in the heap
- HeapSort: remove the root node of the first data and perform the recursive operation of maximum heap adjustment
code
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class HeapSort { /** * Select sort - heap sort * @param array Array to be sorted * @return Sorted array */ public static int[] heapSort(int[] array) { //Here, the index of the element starts from 0, so the last non leaf node array.length/2 - 1 for (int i = array.length / 2 - 1; i >= 0; i--) { adjustHeap(array, i, array.length); //Adjustment reactor } // After the above logic, the heap building is completed // Next, start sorting logic for (int j = array.length - 1; j > 0; j--) { // Element exchange is used to remove the large top heap // Put the root element of the big top heap at the end of the array; In other words, after each heap adjustment, an element will reach its final position swap(array, 0, j); // After the element exchange, there is no doubt that the last element does not need to consider the sorting problem. // The next thing we need to sort is to remove the heap of some elements, which is why this method is placed in the loop // Here, in essence, it is adjusted from top to bottom and from left to right adjustHeap(array, 0, j); } return array; } /** * The most critical part of the whole heap sorting * @param array Stack to be assembled * @param i Starting node * @param length Length of heap */ public static void adjustHeap(int[] array, int i, int length) { // Take out the current element first, because the current element may have to move all the time int temp = array[i]; for (int k = 2 * i + 1; k < length; k = 2 * k + 1) { //2*i+1 is the left subtree of left subtree i (because i starts from 0), and 2*k+1 is the left subtree of K // Let k point to the largest of the child nodes first if (k + 1 < length && array[k] < array[k + 1]) { //If there is a right subtree, and the right subtree is greater than the left subtree k++; } //If it is found that the node (left and right child nodes) is larger than the root node, the values are exchanged if (array[k] > temp) { swap(array, i, k); // If the child node is replaced, the subtree with the child node as the root will be affected. Therefore, the cycle continues to judge the tree where the child node is located i = k; } else { //No exchange, just terminate the loop break; } } } public static void swap(int[] arr, int a, int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } public static void main(String [] args){ int [] arr = {11,5,8,66,4,2,0,44}; System.out.println("Before sorting:"+Arrays.toString(arr)); heapSort(arr); System.out.println("After sorting:"+Arrays.toString(arr)); } }
result
Before sorting: [11, 5, 8, 66, 4, 2, 0, 44]
After sorting: [0, 2, 4, 5, 8, 11, 44, 66]
10. Cardinality sorting
Cardinal sorting belongs to distributive sorting, also known as bucket sort or bin sort. As the name suggests, it allocates the elements to be sorted to some "buckets" through some information of key values, so as to achieve the function of sorting. Cardinal sorting belongs to stable sorting, and its time complexity is O (nlog) ® m) Where r is the adopted cardinality and M is the number of heaps. In some cases, the efficiency of cardinality sorting method is higher than that of other stable sorting methods
example
First step
Taking LSD as an example, it is assumed that there is a string of values as follows:
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
First, according to the value of single digits, assign them to buckets numbered 0 to 9 when visiting the values:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
Step 2
Next, concatenate the values in these buckets to form the following sequence:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
Next, allocate again, this time according to the ten digits:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
Step 3
Next, concatenate the values in these buckets to form the following sequence:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
At this time, the whole sequence has been sorted; If the sorted object has more than three digits, continue the above actions until the highest digit.
The cardinality sorting of LSD is applicable to the sequence with small digits. If there are many digits, the efficiency of using MSD will be better. In contrast to LSD, MSD is allocated based on the high-order number, but it is not merged back into an array immediately after allocation. Instead, a "sub bucket" is established in each "bucket", and the value in each bucket is allocated to the "sub bucket" according to the value of the next digit. After the allocation of the lowest digits is completed, it is merged into the array of receipt 1.
Implementation method
The most significant digital first method (MSD method for short): first sort and group the records according to k1, the key code k1 is equal in the same group, then sort each group according to k2 and divide them into subgroups, and then continue to sort and group the following key codes until the subgroups are sorted according to the next key code kd. Then connect the groups to get an ordered sequence.
Least significant digital first method (LSD method for short): start sorting from kd, then sort kd-1, repeat in turn, and get an ordered sequence after sorting k1.
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class RadixSort { public static void sort(int[] number, int d) //d indicates the maximum number of digits { int k = 0; int n = 1; int m = 1; //Which bit is the sorting basis of control key values int[][] temp = new int[10][number.length]; //The first dimension of the array represents the possible remainder 0-9 int[] order = new int[10]; //The array order[i] is used to represent the number of I bits while(m <= d) { for(int i = 0; i < number.length; i++) { int lsd = ((number[i] / n) % 10); temp[lsd][order[lsd]] = number[i]; order[lsd]++; } for(int i = 0; i < 10; i++) { if(order[i] != 0) for(int j = 0; j < order[i]; j++) { number[k] = temp[i][j]; k++; } order[i] = 0; } n *= 10; k = 0; m++; } } public static void main(String[] args) { int[] data = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100}; System.out.println("Before sorting:"+Arrays.toString(data)); RadixSort.sort(data, 3); System.out.println("After sorting:"+Arrays.toString(data)); } }
result
Before sorting: [73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100]
After sorting: [14, 22, 28, 33, 39, 43, 55, 65, 73, 81, 93, 100]
11. Bucket sorting
Bucket sort, or so-called box sort, is a sort algorithm. Its working principle is to divide the array into a limited number of buckets. Each bucket is sorted individually (it is possible to use another sorting algorithm or continue to use bucket sorting recursively). Bucket sorting is an inductive result of pigeon nest sorting. Bucket sorting uses linear time when the values in the array to be sorted are evenly distributed( Θ (n)). However, bucket sorting is not a comparative sorting. It is not affected by the lower limit of O(n log n).
code
package test1; import java.util.Arrays; /** * @author Xiao Xu * * 2021 October 30 */ public class BucketSort { public static void basket(int data[])//data is the array to be sorted { int n=data.length; int bask[][]=new int[10][n]; int index[]=new int[10]; int max=Integer.MIN_VALUE; for(int i=0;i<n;i++) { max=max>(Integer.toString(data[i]).length())?max:(Integer.toString(data[i]).length()); } String str; for(int i=max-1;i>=0;i--){ for(int j=0;j<n;j++){ str=""; if(Integer.toString(data[j]).length()<max){ for(int k=0;k<max-Integer.toString(data[j]).length();k++) str+="0"; } str+=Integer.toString(data[j]); bask[str.charAt(i)-'0'][index[str.charAt(i)-'0']++]=data[j]; } int pos=0; for(int j=0;j<10;j++){ for(int k=0;k<index[j];k++){ data[pos++]=bask[j][k]; } } for(int x=0;x<10;x++)index[x]=0; } } public static void main(String [] args){ int [] arr ={99,55,44,33,20,11,25,69,50}; System.out.println("Before sorting:"+Arrays.toString(arr)); basket(arr); System.out.println("After sorting:"+Arrays.toString(arr)); } }
result
Before sorting: [99, 55, 44, 33, 20, 11, 25, 69, 50]
After sorting: [11, 20, 25, 33, 44, 50, 55, 69, 99]
Divide and conquer algorithm is used to find the optimal continuous subsequence
This is difficult to understand. It uses the idea of divide and conquer. Many dynamic programming algorithms are very similar to recursion in mathematics. If we can find a suitable recurrence formula, we can easily solve the problem.
package test1; /** * @author Xiao Xu * * 2021 October 30 */ public class test{ public static int matrixChain(int[] p, int[][] m, int[][] s) { int n = p.length - 1; for (int i = 1; i <= n; i++) // Itself is 0 m[i][i] = 0; for (int r = 2; r <= n; r++) { for (int i = 1; i <= n - r + 1; i++) { int j = i + r - 1; m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j]; // Find the multiplication from Ai to Aj s[i][j] = i; // Record division location for (int k = i + 1; k < j; k++) {// Find out whether there are optimized segmentation points int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; // formula if (t < m[i][j]) { m[i][j] = t; s[i][j] = k; } } } } return m[1][n]; } /** * Optimal calculation order of output A[i:j] * @param i,j: Continued multiplication matrix subscript * @param s: An array that holds the subscripts of the split position **/ public static void traceback(int i, int j, int[][] s) { // Optimal calculation order of output A[i:j] if (i == j) { // Recursive exit System.out.print("A"+i); return; } else { System.out.print("("); // Recursive output left traceback(i, s[i][j], s); // Recursive output right traceback(s[i][j] + 1, j, s); System.out.print(")"); } } public static void main(String[] args) { int[] p = new int[]{35,15, 5, 10, 20}; int[][] m = new int[p.length][p.length]; int[][] s = new int[p.length][p.length]; System.out.println("The optimal value is: "+matrixChain(p, m, s)); traceback(1, p.length-1, s); } }
result
The optimal value is 7125
((A1A2)(A3A4))
Implementation of Hanoi Tower in Java
package test1; import java.util.*; import java.util.Scanner; /** * @author Xiao Xu * * 2021 October 30 */ public class shop { //Used to record the number of moves static int m = 0; //Display function public static void move(int disk, char M, char N) { System.out.println("The first" + (++m) + "Operation, will" + disk + "No. plate from" + M + "Move to" + N); } public static void hanoi(int n, char A, char B, char C) { if(n == 1) { move(n, A, C); }else { hanoi(n - 1, A, C, B); move(n, A, C); hanoi(n - 1, B, A, C); } } public static void main(String[] args) { boolean i=true; while(i){ Scanner in = new Scanner(System.in); System.out.println("Please enter hanoi Number of:"); int a = in.nextInt(); hanoi(a, 'A', 'B', 'C'); System.out.println("Total use" + m + "second"); } } }
result
Please enter the number of hanoi:
3
For the first operation, move disk 1 from A to C
For the second operation, move disk 2 from A to B
For the third operation, move disk 1 from C to B
For the fourth operation, move disk 3 from A to C
For the fifth operation, move disk 1 from B to A
For the 6th operation, move disk 2 from B to C
For the 7th operation, move disk 1 from A to C
7 times in total
Please enter the number of hanoi:
Numerical value of each algorithm
Sorting algorithm | Average time complexity |
---|---|
Bubble sorting | O(n²) |
Bubble sorting | O(n²) |
Select sort | O(n²) |
Insert sort | O(n²) |
Shell Sort | O(n1.5) |
Quick sort | O(N*logN) |
Merge sort | O(N*logN) |
Heap sort | O(N*logN) |
Cardinality sort | O(d(n+r)) |