1. Simple sorting
1. Bubble sort O(n^2)
Pairwise comparison, reverse order exchange
public static int[] bubbleSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - i - 1; j++) { if (arr[j] > arr[j + 1]) { arr[j] = arr[j] ^ arr[j+1]; arr[j+1] = arr[j] ^ arr[j+1]; arr[j] = arr[j] ^ arr[j+1]; } } } return arr; }
2. Selection sort O(n^2)
public static int[] selectSort(int[] arr) { int minIndex = -1; for (int i = 0; i < arr.length - 1; i++) { minIndex = i; for (int j = i + 1; j < arr.length; j++) { if(arr[minIndex] > arr[j]) { minIndex = j; } } if(i != minIndex) { arr[i] = arr[minIndex] ^ arr[i]; arr [minIndex] = arr [minIndex] ^ arr [i]; arr[i] = arr[minIndex] ^ arr[i]; } } return arr; }
3. Insertion sort
Insert a record into an already sorted sorted table to get a new sorted table with records incremented by 1
public static int[] insertSort(int[] arr) { int sentinel; int index = -1; for (int i = 1; i < arr.length; i++) { sentinel = arr[i]; if(arr[i] < arr[i - 1]) { // loop compare for (int j = 0; j < i; j++) { if(arr[i] < arr[j]) { index = j; break; } } // move for (int k = i; k > index; k--) { arr[k] = arr[k] ^ arr[k-1]; arr[k-1] = arr[k] ^ arr[k-1]; arr[k] = arr[k] ^ arr[k-1]; } arr[index] = sentinel; } } return arr; }
Second, complex sorting
1. Hill sort O(n^(3/2))
The last increment value of the increment sequence must be equal to 1. The first half of the sequence is taken as the increment, and then halved each time to make the sequence basically orderly until the increment is 1.
It is not implemented, and an increment is added on the basis of direct sorting, which is an incremental comparison of sequences.
2. Heap sort O(nlogn)
It is an improvement on the basis of selection sorting, which builds the sequence into a large top heap, removes the top element of the heap, and rebuilds the remaining elements into a heap
Heap: Complete binary tree, the value of a node greater than or equal to its left and right nodes is called a large top heap, and less than or equal to a small top heap
public static int[] heapSort(int[] arr) { int len = arr.length; // build a large top heap for (int i = len / 2; i > 0 ; i--) { adjustHeap(arr, i-1, len); } for (int i = len - 1; i > 0; i--) { // swap the top data with the last data arr[0] = arr[0] ^ arr[i]; arr[i] = arr[0] ^ arr[i]; arr[0] = arr[0] ^ arr[i]; adjustHeap(arr, 0, i); } return arr; } // adjust the heap structure public static int[] adjustHeap(int[] arr, int curInd, int len) { int tmp = arr[curInd]; // The current node is compared with its own node to exchange child nodes: 2*curIndex 2*curIndex+1 for(int i = (curInd + 1) * 2; i <= len; i++) { // Determine the size of the left and right nodes, and set i to the larger value index if (i < len && arr[i-1] < arr[i]) { ++i; } // Compare parent node with larger child node if (arr[curInd] > arr[i-1]) { break; } arr [curInd] = arr [curInd] ^ arr [i-1]; arr[i - 1] = arr[curInd] ^ arr[i-1]; arr [curInd] = arr [curInd] ^ arr [i-1]; curInd = i - 1; } arr [curInd] = tmp; return arr; }
3. Merge Sort
Use recursion and divide-and-conquer techniques to divide the data sequence into smaller and smaller half-sublists, then sort the half-sublists, and finally use recursive steps to merge the sorted half-sublists into larger and larger ordered sequences
public static int[] mergeSort(int[] arr, int first, int last) { if ((first + 1) < last) { int mid = (first + last) / 2; mergeSort(arr, first, mid); mergeSort(arr, mid, last); merge(arr, first, mid, last); } return arr; } public static void merge(int[] arr, int first, int mid, int last) { int[] tmp = new int[last - first]; int indexL = first, indexR = mid, index = 0; while(indexL < mid && indexR < last) { if (arr[indexL] < arr[indexR]) { tmp[index] = arr[indexL]; indexL++; } else { tmp[index] = arr[indexR]; indexR++; } index ++; } while (indexL < mid) { tmp[index] = arr[indexL]; index ++; indexL++; } while (indexR < last) { tmp[index] = arr[indexR]; index ++; indexR++; } index = 0; for (int i = first; i < last; i++) { arr[i] = tmp[index]; index ++; } }
4. Quick sort O(nlogn)
After one sorting, it is divided into 2 parts, one part is larger than the other part
public static int[] quickSort(int[] arr, int low, int high) { int privot; if (low < high) { privot = partition(arr, low, high); quickSort(arr, low, privot - 1); quickSort(arr, privot + 1, high); } return arr; } public static int partition(int[] arr, int low, int high) { int privotKey = arr[low]; while (low < high) { while (low < high && privotKey <= arr[high]) { high--; } swap(arr, low, high); while (low < high && privotKey >= arr[low]) { low++; } swap(arr, low, high); } return low; } public static void swap(int[] arr, int i1, int i2) { if (i1 != i2) { arr[i1] = arr[i1] ^ arr[i2]; arr[i2] = arr[i1] ^ arr[i2]; arr[i1] = arr[i1] ^ arr[i2]; } }
Optimization: random selection, middle of three numbers