对于插入排序,我们一点都不陌生(pseudo code):
for i = [1, arr.length)
{
j = i - 1
key = arr[i]
while (arr[j] < key and j >= 0)
{
arr[j + 1] = arr[j]
--j
}
arr[j + 1] = key
}
最坏情况时间复杂度:O(n^2)
二分查找:
/*
*@desc 搜索范围:[low, high)
*@分析:
*1.low == high return low|mid|high
*2.low < high continue to recursive
*3.low > high return low
* 3.a. 因为 mid < high ( low < high && mid == (low + high)/2 => mid < (2high/2 = high) ) 恒成立,
* 故不可能存在:low = mid + 1 > high
* 3.b. 因为存在 mid == low (mid == (low + high)/2 == [(2low + 1) / 2] == low ),
* 故有:high = mid - 1 < low,此时high已失真,故取low
*4.关于溢出
* 4.a. 在tagA中mid = 0, return mid
* 4.b. 在tagB中mid = MAX, 由于high <= MAX, 由3.a.知, 显然不可能
*@return size_t 若存在,则返回相应索引;否则返回可以提供插入的索引
**/
if (low >= high)
{
return low
}
mid = (low + high) / 2
if (key == arr[mid])
{
return mid
}
if (key < arr[mid])
{
if (0 == mid)//tagA
{
return mid;
}
high = mid - 1
} else
{
low = mid + 1
//tagB
}
return binary_search(arr, key, low, high)
最坏情况时间复杂度:O(lgn)
像这样:
for i = [1, length)
{
pos = binary_search(arr, arr[i], 0, i)
key = arr[i]
if (key > arr[pos])
{
++pos
}
for j = [i,pos)
{
arr[j] = arr[j - 1]
}
arr[pos] = key
}
显然,查找的效率肯定是提高了,这部分的最坏情况时间复杂度为:O( lg(n-1)! ) < O(nlgn)
然而,这始终无法改善它在插入部分的效率,最坏情况依旧需要向右移动i个元素,这部分的时间复杂度为: O(n^2)
所以,总的时间复杂度为:O(n^2)