1 package ren.laughing.datastructure.algorithm; 2 /** 3 * 排序 4 * @author Laughing_Lz 5 * @time 2016年4月22日 6 */ 7 public class Sorter { 8 /** 9 * 直接插入排序(从小到大) 时间复杂度为O(n^2) 10 * 11 * @param arr 12 * 要排序的数组 13 * @param low 14 * 要排序的最低下标 15 * @param high 16 * 要排序的最高下标 17 * @return 排序后的数组 18 */ 19 public static void insertSort(int[] arr, int low, int high) { 20 for (int i = low + 1; i <= high; i++) { 21 int temp = arr[i];// 待插入元素 22 int j = i;// 记录待插入位置 23 for (; j > low && temp < arr[j - 1]; j--) {// 24 arr[j] = arr[j - 1];// 后移 25 } 26 arr[j] = temp;// 插入 27 } 28 printResult("直接插入排序:", arr); 29 } 30 31 /** 32 * 折半插入排序 时间复杂度仍为O(n^2) 33 * 34 * @param arr 35 * @param low 36 * @param high 37 * @return 38 */ 39 public static void binInsertSort(int[] arr, int low, int high) { 40 for (int i = low + 1; i <= high; i++) { 41 int temp = arr[i]; 42 int lo = low; 43 int hi = i - 1; 44 while (lo <= hi) {// 注意'=' ★ 45 int mid = (lo + hi) / 2; 46 if (temp < arr[mid]) { 47 hi = mid - 1;// 由此看出最终temp的位置在hi+1 48 } else { 49 lo = mid + 1;// hi+1等同于lo (此处应该没错吧?) 50 } 51 } 52 for (int j = i - 1; j > hi; j--) {// 后移 53 arr[j + 1] = arr[j]; 54 } 55 arr[hi + 1] = temp;// 插入 56 } 57 printResult("折半插入排序:", arr); 58 } 59 60 /** 61 * 希尔排序(缩小增量排序) 当n在某个范围内,时间复杂度可达到O(n^1.3) 62 * 63 * @param arr 64 * @param low 65 * @param high 66 * @param delta 67 * 步长序列 68 */ 69 public static void shellSort(int[] arr, int low, int high, int[] delta) { 70 for (int i = 0; i < delta.length; i++) {// 第一步:遍历步长序列 71 for (int m = low; m < low + delta[i]; m++) {// 第二步:循环起始点,保证每个被拆分的子序列都被直接排序 72 for (int j = m + delta[i]; j <= high; j += delta[i]) {// 对每个子序列直接排序 73 int temp = arr[j]; 74 int k = j; 75 for (; k > m && temp < arr[(k - delta[i])]; k -= delta[i]) { 76 arr[k] = arr[(k - delta[i])];// 后移 77 } 78 arr[k] = temp;// 插入 79 } 80 } 81 } 82 printResult("希尔排序:", arr); 83 } 84 85 /** 86 * 冒泡排序 时间复杂度为O(n^2) 87 * 88 * @param arr 89 * @param low 90 * @param high 91 */ 92 public static void bubbleSort(int[] arr, int low, int high) { 93 int len = high - low + 1; 94 for (int i = 1; i < len; i++) { 95 for (int j = low; j <= high - i; j++) {// 这里j<= high-i ★ 96 if (arr[j] > arr[j + 1]) { 97 int temp = arr[j];// 交换 98 arr[j] = arr[j + 1]; 99 arr[j + 1] = temp; 100 } 101 } 102 } 103 printResult("冒泡排序:", arr); 104 } 105 106 /** 107 * 快速排序 需要递归 108 * 109 * @param arr 110 * @param low 111 * @param high 112 */ 113 public static void quickSort(int[] arr, int low, int high) { 114 if (low < high) { 115 int pa = partition(arr, low, high);// 分治 116 quickSort(arr, low, pa - 1); 117 quickSort(arr, pa + 1, high); 118 } 119 } 120 121 /** 122 * 将序列划分为两个子序列并返回枢轴元素的位置 123 * 124 * @param arr 125 * @param low 126 * 划分区间 127 * @param high 128 * @return 129 */ 130 private static int partition(int[] arr, int low, int high) { 131 int pivot = arr[low];// 首先定义枢轴为low所指元素 132 while (low < high) {// 交替扫描 133 while (arr[high] > pivot && low < high) { 134 high--; 135 } 136 arr[low] = arr[high];// 将比 pivot 小的元素移向低端 137 while (arr[low] < pivot && low < high) { 138 low++; 139 } 140 arr[high] = arr[low];// 将比 pivot 大的元素移向高端 141 } 142 arr[low] = pivot;// 设置枢轴 143 return low; 144 } 145 146 /** 147 * 程序入口 148 * 149 * @param args 150 */ 151 public static void main(String[] args) { 152 int[] arr = new int[] { 2, 5, 7, 3, 4, 8, 1, 9, 6, 0 }; 153 int[] delta = new int[] { 5, 3, 1 }; 154 // insertSort(arr, 0, 9); 155 // binInsertSort(arr, 0, 9); 156 // shellSort(arr, 0, 9, delta); 157 // bubbleSort(arr, 0, 9); 158 quickSort(arr, 0, 9); 159 printResult("快速排序:", arr); 160 } 161 162 /** 163 * 打印 164 * 165 * @param str 166 * @param arr 167 */ 168 public static void printResult(String str, int[] arr) { 169 System.out.print(str); 170 for (int i = 0; i < arr.length; i++) { 171 System.out.print(arr[i] + " "); 172 } 173 System.out.println(); 174 } 175 }