② A[M] > T,中间值右侧的其它元素都大于 T,无需比较,中间索引左边去找,M - 1 设置为右边界,重新查找
③ A[M] < T,中间值左侧的其它元素都小于 T,无需比较,中间索引右边去找,M + 1 设置为左边界,重新查找
当 L > R 时,表示没有找到,应结束循环
算法实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicstaticintbinarySearch(int[] a, int t) { intl=0, r = a.length - 1, m; while (l <= r) { m = (l + r) / 2; if (a[m] == t) { return m; } elseif (a[m] > t) { r = m - 1; } else { l = m + 1; } } return -1; }
publicstaticvoidselection(int[] a) { for (inti=0; i < a.length - 1; i++) { // i 代表每轮选择最小元素要交换到的目标索引 ints= i; // 代表最小元素的索引 for (intj= s + 1; j < a.length; j++) { if (a[s] > a[j]) s = j; // j 元素比 s 元素还要小, 更新 s } if (s != i) { swap(a, s, i); } System.out.println(Arrays.toString(a)); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
voidswap(int *a,int *b){ int temp = *a; *a = *b; *b = temp; } voidselection_sort(int arr[], int len){ int i,j; for (i = 0 ; i < len - 1 ; i++){ int min = i; for (j = i + 1; j < len; j++){ if (arr[j] < arr[min]) min = j; } swap(&arr[min], &arr[i]); } }
// 修改了代码与希尔排序一致 publicstaticvoidinsert(int[] a) { for (inti=1; i < a.length; i++) { intt= a[i]; // 代表待插入的元素值 intj= i; // 已排序部分最后元素的索引 System.out.println(j); while (j > 0 && t < a[j - 1]) { a[j] = a[j - 1]; // j-1 是上一元素索引,若 > t,后移 j--; } if (j != i) a[j] = t; // 找到比 t 小的了,就插入在 j 这个位置 System.out.println(Arrays.toString(a) + " " + j); } }
1 2 3 4 5 6 7 8 9 10 11 12
voidinsertion_sort(int arr[], int len){ int i,j,temp; for (i=1;i<len;i++){ temp = arr[i]; j=i-1; while((j>=0) && (arr[j]>temp)) { arr[j+1] = arr[j]; j--; } arr[j+1] = temp; } }
与选择排序比较
二者平均时间复杂度都是 $O(n^2)$
大部分情况下,插入都略优于选择。小数据量排序,都会优先选择插入排序
有序集合插入的时间复杂度为 $O(n)$
插入属于稳定排序算法,而选择属于不稳定排序
希尔排序
算法描述
首先选取一个间隙序列,如 (n/2,n/4 … 1),n 为数组长度
每一轮将间隙相等的元素视为一组,对组内元素进行插入排序,目的有二
① 少量元素插入排序速度很快
② 让组内值较大的元素更快地移动到后方
当间隙逐渐减少,直至为 1 时,即可完成排序
算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
privatestaticvoidshell(int[] a) { for (intgap= a.length / 2; gap > 0; gap /= 2) { for (inti= gap; i < a.length; i++) { intt= a[i]; // 代表待插入的元素值 intj= i; while (j >= gap && t < a[j - gap]) { // 每次与上一个间隙为 gap 的元素进行插入排序 a[j] = a[j - gap]; // j-gap 是上一个元素索引,如果 > t,后移 j -= gap; } a[j] = t; System.out.println(Arrays.toString(a) + " gap:" + gap); } } }
1 2 3 4 5 6 7 8 9 10 11 12
voidshell_sort(int arr[], int len) { int gap, i, j; int temp; for (gap = len >> 1; gap > 0; gap >>= 1){ for (i = gap; i < len; i++) { temp = arr[i]; for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) arr[j + gap] = arr[j]; arr[j + gap] = temp; } } }