要开始准备刷题啦!排序算法知识点总结,对数器的实现,master公式,小和问题,逆序对问题。Sort1包括冒泡排序,选择排序,插入排序,归并排序。
冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 package basic_class_01;import java.util.Arrays;public class Code_00_BubbleSort { public static void bubbleSort (int [] arr) { if (arr == null || arr.length < 2 ) { return ; } for (int e = arr.length - 1 ; e > 0 ; e--) { for (int i = 0 ; i < e; i++) { if (arr[i] > arr[i + 1 ]) { swap(arr, i, i + 1 ); } } } } public static void swap (int [] arr, int i, int j) { arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } public static void comparator (int [] arr) { Arrays.sort(arr); } public static int [] generateRandomArray(int maxSize, int maxValue) { int [] arr = new int [(int ) ((maxSize + 1 ) * Math.random())]; for (int i = 0 ; i < arr.length; i++) { arr[i] = (int ) ((maxValue + 1 ) * Math.random()) - (int ) (maxValue * Math.random()); } return arr; } public static int [] copyArray(int [] arr) { if (arr == null ) { return null ; } int [] res = new int [arr.length]; for (int i = 0 ; i < arr.length; i++) { res[i] = arr[i]; } return res; } public static boolean isEqual (int [] arr1, int [] arr2) { if ((arr1 == null && arr2 != null ) || (arr1 != null && arr2 == null )) { return false ; } if (arr1 == null && arr2 == null ) { return true ; } if (arr1.length != arr2.length) { return false ; } for (int i = 0 ; i < arr1.length; i++) { if (arr1[i] != arr2[i]) { return false ; } } return true ; } public static void printArray (int [] arr) { if (arr == null ) { return ; } for (int i = 0 ; i < arr.length; i++) { System.out.print(arr[i] + " " ); } System.out.println(); } public static void main (String[] args) { int testTime = 500000 ; int maxSize = 100 ; int maxValue = 100 ; boolean succeed = true ; for (int i = 0 ; i < testTime; i++) { int [] arr1 = generateRandomArray(maxSize, maxValue); int [] arr2 = copyArray(arr1); bubbleSort(arr1); comparator(arr2); if (!isEqual(arr1, arr2)) { succeed = false ; break ; } } System.out.println(succeed ? "Nice!" : "Fuck!" ); int [] arr = generateRandomArray(maxSize, maxValue); printArray(arr); bubbleSort(arr); printArray(arr); } }
时间复杂度 O(N^2)
额外空间复杂度 O(1)
选择排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.util.Arrays;public class Code_01_SelectionSort { public static void selectionSort (int [] arr) { if (arr == null || arr.length < 2 ) { return ; } for (int i = 0 ; i < arr.length; i++) { int minIndex = i; for (int j = i + 1 ; j < arr.length; j++) { minIndex = arr[j] < arr[minIndex] ? j : minIndex; } swap(arr, i, minIndex); } } public static void swap (int [] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } }
时间复杂度 O(N^2)
额外空间复杂度 O(1)
插入排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Code_02_InsertionSort { public static void insertionSort (int [] arr) { if (arr == null || arr.length < 2 ) { return ; } for (int i = 1 ; i < arr.length; i++) { for (int j = i - 1 ; j >=0 && arr[j] > arr[j + 1 ]; j--) { swap(arr, j, j + 1 ); } } } public static void swap (int [] arr, int i, int j) { arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } }
差不多已经排序的数组,小数组可以用插入排序。完全有序O(N),逆序O(N^2)。
时间复杂度 O(N^2) :
顺序:只需比较N-1次,O(N)
逆序:需比较 1+2+3+…+N-1次,O(N^2)
额外空间复杂度 O(1)
归并排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Code_03_MergeSort { public static void mergeSort (int [] arr) { if (arr == null || arr.length < 2 ) { return ; } mergeSort(arr, 0 , arr.length - 1 ); } public static void mergeSort (int [] arr, int l, int r) { if (l == r) { return ; } int mid = l + ((r - l) >> 1 ); mergeSort(arr, l, mid); mergeSort(arr, mid + 1 , r); merge(arr, l, mid, r); } public static void merge (int [] arr, int l, int m, int r) { int [] help = new int [r - l + 1 ]; int i = 0 ; int p1 = l; int p2 = m + 1 ; while (p1 <= m && p2 <= r) { help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; } while (p1 <= m) { help[i++] = arr[p1++]; } while (p2 <= r) { help[i++] = arr[p2++]; } for (i = 0 ; i < help.length; i++) { arr[l + i] = help[i]; } } }
master 公式
小和问题和逆序对问题
小和问题代码: 可以利用类似于归并排序的分治思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class Code_12_SmallSum { public static int smallSum (int [] arr) { if (arr == null || arr.length < 2 ) { return 0 ; } return smallSum(arr, 0 , arr.length - 1 ); } public static int smallSum (int [] arr, int l, int r) { if (l == r) { return 0 ; } int mid = l + ((r - l) >> 1 ); return smallSum(arr, l, mid) + smallSum(arr, mid + 1 , r) + merge(arr, l, mid, r); } public static int merge (int [] arr, int l, int m, int r) { int [] help = new int [r-l+1 ]; int i = 0 ; int p1 = l; int p2 = m + 1 ; int res = 0 ; while (p1 <= m && p2 <= r) { res += arr[p1] < arr[p2] ? (arr[p1] * (r - p2 + 1 )) : 0 ; help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; } while (p1 <= m) { help[i++] = arr[p1++]; } while (p2 <= r) { help[i++] = arr[p2++]; } for (i = 0 ; i < help.length; i++) { arr[l + i] = help[i]; } return res; } }
逆序对问题也一样。