- package lhz.algorithm.chapter.two;
- /**
- * “二分插入排序”,利用二分查找优化插入排序中的定位部分。
- * 《算法导论》,习题2.3-6
- * Observe that the while loop of lines 5 - 7 of the INSERTION-SORT procedure in
- * Section 2.1 uses a linear search to scan (backward) through the sorted
- * subarray A[1 j - 1]. Can we use a binary search (see Exercise 2.3-5)
- * instead to improve the overall worst-case running time of insertion sort to
- * Θ(n lg n)?
- * 本文地址:http://mushiqianmeng.blog.51cto.com/3970029/732333
- *@author lihzh(苦逼coder)
- */
- public class InsertSortWithBinarySearch {
- private static int[] input = new int[] { 2, 1, 5, 4, 9, 8, 6, 7, 10, 3 };
- public static void main(String[] args) {
- //从数组第二个元素开始排序,因为第一个元素本身肯定是已经排好序的
- for (int j = 1; j < input.length; j++) {// 复杂度 n
- //保存当前值
- int key = input[j];
- //利用二分查找定位位置
- int index = binarySearch(input, input[j], 0, j - 1);//复杂度:lgn
- //将目标插入位置,同时右移目标位置右边的元素
- for (int i = j; i > index ; i--) {//复杂度,最差情况:(n-1)+(n-2)+...+n/2=Θ(n^2)
- input[i] = input [i-1];
- }
- input[index] = key;
- }
- /*
- * 复杂度分析:
- * 最佳情况,即都已经排好序,则无需右移,此时时间复杂度为:Θ(n lg n)
- * 最差情况,全部逆序,此时复杂度为Θ(n^2)
- * 所以针对2.3-6问题,无法将最差情况的复杂度提升到Θ(n lg n)。
- */
- //打印数组
- printArray();
- }
- /**
- * 二分查找
- * @param input 给定已排序的待查数组
- * @param target 查找目标
- * @param from 当前查找的范围起点
- * @param to 当前查找的返回终点
- * @return 返回目标在数组中,按顺序应在的位置
- */
- private static int binarySearch(int[] input, int target, int from, int to) {
- int range = to - from;
- //如果范围大于0,即存在两个以上的元素,则继续拆分
- if (range > 0) {
- //选定中间位
- int mid = (to + from) / 2;
- //如果临界位不满足,则继续二分查找
- if (input[mid] > target) {
- return binarySearch(input,target,from,mid-1);
- } else {
- return binarySearch(input,target,mid+1,to);
- }
- } else {
- if (input[from] > target) {
- return from;
- } else {
- return from + 1;
- }
- }
- }
- private static void printArray() {
- for (int i : input) {
- System.out.print(i + " ");
- }
- }
- }
本文转自mushiqianmeng 51CTO博客,原文链接:http://blog.51cto.com/mushiqianmeng/732333,如需转载请自行联系原作者