算法模板
排序
冒泡:
public static void bubbleSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int e = arr.length - 1; e > 0; e --) { // 0 ~ e范围上交换, 挨个冒泡 for (int i = 0; i < e; i ++) { if (arr[i] > arr[i + 1]) { swap(arr, i, i + 1); } } } }
选择:
public static void selectSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int i = 0; i < arr.length; i ++) { // i ~ N - 1 int minIndex = i; for (int j = i + 1; j < arr.length; j ++) { // i ~ N - 1上找最小值的下标 minIndex = arr[j] < arr[minIndex] ? j : minIndex; } swap(arr, i , minIndex); } }
插入:
public static void insertionSort(int[] arr) { if (arr == null || arr.length < 2) { return; } // 0 ~ 0已经有序了 // 0 ~ i 想有序 for (int i = 1; i < arr.length; i ++) { // 使0 ~ i有序 // 当前位置的数换到比前一个数小或者数组越界之后停止 for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j --) { swap(arr, j, j + 1); } } }
归并:
public static void mergeSort(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; // p1和p2位置都不越界的时候,拷贝小点的数 // while循环停止的时候,必有一个会越界 while (p1 <= M && p2 <= R) { help[i ++] = arr[p1] <= arr[p2] ? arr[p1 ++] : arr[p2 ++]; } // 两个while只会中一个 // p1没越界,就全部拷贝p1到help中 while (p1 <= M) { help[i ++] = arr[p1 ++]; } // p2没越界,就全部拷贝p2到help中 while (p2 <= R) { help[i ++] = arr[p2 ++]; } for (i = 0; i < help.length; i ++) { arr[L + i] = help[i]; } } /** * 使左右两边有序 * @param arr * @param L * @param R */ public static void process(int[] arr, int L, int R) { if (L == R) { return; } int mid = L + ((R - L) >> 1); // 使左边有序 process(arr, L, mid); // 使右边有序 process(arr, mid + 1, R); // 整体merge mergeSort(arr, L, mid, R); }
快排:
public static void process(int[] arr) { if (arr == null || arr.length < 2){ return; } quickSort(arr, 0, arr.length - 1); } public static void quickSort(int[] arr, int L, int R) { if ( L < R) { swap(arr, L + (int) (Math.random() * (R - L + 1)), R); int[] p = partition(arr, L, R); quickSort(arr, L, p[0] - 1); quickSort(arr, p[1] + 1, R); } } public static int[] partition(int[] arr, int l, int r) { int less = l - 1; int more = r; while (l < more) { if (arr[l] < arr[r]) { swap(arr, ++ less, l++); } else if (arr[l] > arr[r]) { swap(arr, -- more, l); } else { l ++; } } swap(arr, more, r); return new int[] { less + 1, more }; }
堆排:
-
先传入一个数组,将这个数组进行heapify(堆化),组成大根堆之后,将数组的第一个位置和最后一个位置进行交换,此时数组中的最大数找到了他的位置,将heapSize--,将最后一个数和heap断掉练习,反复执行这个过程直到所有的数字都找到了属于他的位置,排序完成
public static void heapSort(int[] arr) { if (arr == null || arr.length < 2) { return; } // 数组整体转为大根堆 for (int i = 0; i < arr.length; i++) { heapInsert(arr, i); } int size = arr.length; // 0位置的数和堆上最后一个数进行交换 swap(arr, 0, --size); // 如果heapSize大于0.代表堆上还有数字,一直进行交换 while (size > 0) { heapify(arr, 0, size); swap(arr, 0, --size); } } public static void heapInsert(int[] arr, int index) { while (arr[index] > arr[(index - 1) / 2]) { swap(arr, index, (index - 1) /2); index = (index - 1)/2 ; } } // 堆化 public static void heapify(int[] arr, int index, int size) { int left = index * 2 + 1; while (left < size) { int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left; largest = arr[largest] > arr[index] ? largest : index; if (largest == index) { break; } swap(arr, largest, index); index = largest; left = index * 2 + 1; } }