题目
观察一下2.1节给出INSERTION-SORT过程,在第5~7行的while循环中,采用了一种线性查找策略,在已排序的子数组A[1...j-1]中(反向)扫描。是否可以用二分查找策略,来将插入排序的总体最坏情况运行时间改善至
分析
INSERTION_SORT(A)
1 for j <- 2 to length(A)
2 do key <- A[j]
3 #将A[j]插入到排列好的A[1…j-1]中
4 i <- j - 1
5 while i > 0 and A[i] > key
6 do A[i+1] <- A[i]
7 i <- i - 1
8 A[i+1] <- key
1 for j <- 2 to length(A)
2 do key <- A[j]
3 #将A[j]插入到排列好的A[1…j-1]中
4 i <- j - 1
5 while i > 0 and A[i] > key
6 do A[i+1] <- A[i]
7 i <- i - 1
8 A[i+1] <- key
将while循环替换为二分查找后,伪代码如下所示:
伪代码
# BINARY-INSERTION-SORT(A)
# for j <- 2 to length(A)
# do key <- A[j]
# i = BINARY-SEARCH-INSERTION(A, 1, j-1, key)
# while j > i
# do A[j] <- A[j-1]
# j <- j-1
# A[i] <- key
# BINARY-SEARCH-INSERTION(A, p, r, v)
# if p <= r
# then q <-
# if A[q] = v
# then return q
# else if A[q] > v
# then return BINARY-SEARCH-INSERTION(A, p, q-1, v)
# else return BINARY-SEARCH-INSERTION(A, q+1, r, v)
# return p
# for j <- 2 to length(A)
# do key <- A[j]
# i = BINARY-SEARCH-INSERTION(A, 1, j-1, key)
# while j > i
# do A[j] <- A[j-1]
# j <- j-1
# A[i] <- key
# BINARY-SEARCH-INSERTION(A, p, r, v)
# if p <= r
# then q <-
# if A[q] = v
# then return q
# else if A[q] > v
# then return BINARY-SEARCH-INSERTION(A, p, q-1, v)
# else return BINARY-SEARCH-INSERTION(A, q+1, r, v)
# return p
在最坏情况下,while j > i的循环的时间复杂度为theta(n),所以整个for循环的时间复杂度为theta(n^2),因此不能将插入排序的总体最坏运行时间改善至
。
Pyhton实现
def binary_search_insertion(a, p, r, v):
if p <= r:
q = (p + r) / 2
if a[q] == v:
return q
elif a[q] > v:
return binary_search_insertion(a, p, q-1, v)
else:
return binary_search_insertion(a, q+1, r, v)
return p
def binary_insertion_sort(a):
for j in range(1, len(a)):
key = a[j]
i = binary_search_insertion(a, 0, j-1, key)
while j > i:
a[j] = a[j-1]
j -= 1
a[i] = key