Java: Sort
选择排序:
protected static void selectSort(int[] array){ int tmp; int minIndex; for(int i = 0; i < array.length - 1; i++){ minIndex = i; for(int j = i + 1; j < array.length; j++){ if(array[j] < array[minIndex]){ minIndex = j; } } if(minIndex != i){ tmp = array[minIndex]; array[minIndex] = array[i]; array[i] = tmp; } } }
插入排序:
protected static void insertSort(int[] array){ int tmp; for(int i = 1; i < array.length; i++){ tmp = array[i]; int j = i - 1; // 有序区最大索引 while(j >= 0){ if(array[j] > tmp){ array[j + 1] = array[j]; }else{ // array[j + 1] = tmp; // 不能在此处, tmp为最小值时, 不会执行 // System.out.printf("\033[37;7m %s -- %s \033[0m\n", j + 1, tmp); break; } j--; } array[j + 1] = tmp; // j + 1 // System.out.println("\033[37;7m>>>>>> " + Arrays.toString(array) + " <<<<<<\033[0m"); } }
for循环格式插入
public class Sort{ public static void main(String[] args){ Random random = new Random(System.currentTimeMillis()); int[] ints = new int[10]; for(int i = 0; i < ints.length; i++){ ints[i] = random.nextInt(10) + 1; } int[] copy = Arrays.copyOfRange(ints, 0, ints.length); Arrays.sort(copy); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(copy) + " <<<<<<\033[0m"); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(ints) + " <<<<<<\033[0m"); shellSort(ints); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(ints) + " <<<<<<\033[0m"); } private static void shellSort(int[] array){ if(array.length < 2) return; // [7, 7, 3, 10, 6, 1, 3, 8, 3, 2] // [7, 7, 7, 7, 7, 7, 7, 7, 8, 10] int key; int cursor; for(int i = 1; i < array.length; i++){ key = array[i]; for(cursor = i - 1; cursor >= 0; cursor--){ if(key < array[cursor]){ array[cursor + 1] = array[cursor]; }else{ // array[cursor + 1] = key; // 当key为最小值时, for循环结束没有把key赋值给有序区的最小值(即 cursor+1) break; } } array[cursor + 1] = key; // 必须等for循环结束时, 才能找到key的位置 } } }
private static void shellSort(int[] array){ if(array.length < 2) return; int key; int cursor; for(int i = 1; i < array.length; i++){ key = array[i]; cursor = i - 1; while(cursor >= 0){ if(key < array[cursor]){ array[cursor + 1] = array[cursor]; }else{ break; } cursor--; } array[cursor + 1] = key; } }
希尔排序
public class Sort{ public static void main(String[] args){ Random random = new Random(System.currentTimeMillis()); int[] ints = new int[10]; for(int i = 0; i < ints.length; i++){ ints[i] = random.nextInt(10) + 1; } int[] copy = Arrays.copyOfRange(ints, 0, ints.length); Arrays.sort(copy); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(copy) + " <<<<<<\033[0m"); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(ints) + " <<<<<<\033[0m"); shellSort(ints); System.out.println("\033[37;7m>>>>>> " + Arrays.toString(ints) + " <<<<<<\033[0m"); } private static void shellSort(int[] array){ if(array.length < 2) return; int key, cursor; // step不断变小, 分组随之变少, 分组数 = step for(int step = array.length / 2; step > 0; step /= 2){ // i++: 才能保证所有分组比较, i+=step: 只进行了一个分组迭代 /** * 迭代过程(设有三个分组0,1,2): 迭代过程每个分组的有序区不断交替变大 * 第一轮: 0,1,2 每个分组有序区+1 => 2 * 第二轮: 0,1,2 每个分组有序区+1 => 3 * 第三轮: 0,1,2 每个分组有序区+1 => 4 * ... */ for(int i = step; i < array.length; i++){ key = array[i]; cursor = i - step; while(cursor >= 0){ if(key < array[cursor]){ array[cursor + step] = array[cursor]; }else{ break; } cursor -= step; } array[cursor + step] = key; } } } }
单边快排
private static void quickSort(int[] array, int low, int high){ if(low > high){ // low==high: 分区只有一个值, low>high: pivot为分区极小值, pivot为分区极大值: 此时右分区low为high+1, 不满足条件 return; } int base = partition(array, low, high); quickSort(array, low, base - 1); // 左分区 quickSort(array, base + 1, high); // 右分区 } private static int partition(int[] array, int low, int high){ int pivot = array[high]; int base = low; int tmp; for(int cursor = base; cursor < high; cursor++){ // base左边的值小于pivot if(array[cursor] < pivot){ if(cursor != base){ tmp = array[cursor]; array[cursor] = array[base]; array[base] = tmp; } base++; // base右移 } } if(base != high && array[base] != array[high]){ // base==high, pivot为分区最大值 tmp = array[base]; array[base] = pivot; array[high] = tmp; } return base; }
双边快排
private static void doubleQuickSort(int[] array, int low, int high){ // System.out.printf("\033[37;7m low: %d, high: %d \033[0m\n", low, high); if(low >= high) return; int partition = partition(array, low, high); doubleQuickSort(array, low, partition - 1); doubleQuickSort(array, partition + 1, high); } private static int partition(int[] array, int low, int high){ int pivot = array[low]; int lowCursor = low + 1; int highCursor = high; int tmp; while(lowCursor < highCursor){ while(pivot < array[highCursor]){ highCursor--; } while(lowCursor < highCursor && array[lowCursor] <= pivot){ lowCursor++; } if(lowCursor == highCursor){ System.out.printf("\033[37;7m Cursor: %d, lowCursor == highCursor \033[0m\n", lowCursor); break; }else{ tmp = array[lowCursor]; array[lowCursor] = array[highCursor]; array[highCursor] = tmp; } } tmp = array[highCursor]; array[highCursor] = pivot; array[low] = tmp; return lowCursor; }
归并排序
private static void mergeSort(int[] array, int low, int high){ if(low < high){ int mid = (low + high) / 2; mergeSort(array, low, mid); // divide mergeSort(array, mid + 1, high); // divide merge(array, low, mid, high); // merge } } private static void merge(int[] array, int low, int mid, int high){ int[] ints = new int[high - low + 1]; int lowCursor = low; int highCursor = mid + 1; int intsCursor = 0; while(lowCursor <= mid && highCursor <= high){ if(array[lowCursor] < array[highCursor]){ ints[intsCursor++] = array[lowCursor++]; }else{ ints[intsCursor++] = array[highCursor++]; } } while(lowCursor <= mid){ // [low, mid] 长 ints[intsCursor++] = array[lowCursor++]; } while(highCursor <= high){ ints[intsCursor++] = array[highCursor++]; } System.arraycopy(ints, 0, array, low, ints.length); }