def:第i个顺序统计量,是该集合中第i小的元素。
def:选择问题:输入,一个包含n个数的集合A,和一个整数i, 1<=i<=n。输出,元素x属于A,且A中恰好有i-1个其他元素小于它。
9.1 最大值和最小值
寻找一个数组中的最大值和最小值需要经过n-1次比较找到
def MINIMUM(A):
mini = A[0]
for i in range(1, len(A)):
if mini > A[i]:
mini = A[i]
return mini
def MAXIMUM(A):
maxi = A[0]
for i in range(1, len(A)):
if maxi < A[i]:
maxi = A[i]
return maxi
而同时寻找最大值与最小值则可以通过同时取两个数进行比较得到3*(n//2)次比较得到
def MINIMUM_MAXIMUM(A):
n = len(A)
start = 0
if n % 2 == 0:
start = 2
S = A[ : start]
mini = MINIMUM(S)
maxi = MAXIMUM(S)
else:
start = 3
S = A[ : start]
mini = MINIMUM(S)
maxi = MAXIMUM(S)
for i in range(start, len(A), 2):
if A[i] > A[i + 1]:
mn = A[i + 1]
mx = A[i]
else:
mn = A[i]
mx = A[i + 1]
if mn < mini:
mini = mn
if mx > maxi:
maxi = mx
return mini, maxi
9.2 期望为线性时间的选择算法
期望为线性时间的选择算法,利用parttion将数组分组,最坏情况为n^2,期望运行时间为n
def PARTITION(A, p, r):
x = A[r]
i = p
for j in range(p, r):
if A[j] <= x:
temp = A[i]
A[i] = A[j]
A[j] = temp
i = i + 1
temp = A[i]
A[i] = A[r]
A[r] = temp
return i
def RANDOMIZED_PARTITION(A, p, r):
i = random.randint(p, r)
temp = A[i]
A[i] = A[r]
A[r] = temp
return PARTITION(A, p, r)
def RANDOMIZED_SELECT(A, p, r, i):
if p == r:
return A[p]
q = RANDOMIZED_PARTITION(A, p, r)
k = q-p+1
if i == k:
return A[q]
elif i < k:
return RANDOMIZED_SELECT(A, p, q-1, i)
else:
return RANDOMIZED_SELECT(A, q+1, r, i-k)
算法效率的证明过程与快速排序一样,利用随机变量指示器证明其期望运行时间。
9.3 最坏情况为线性时间的选择算法
找到数组的第k位数,然后根据这个数对数组做划分,再在相对应的子数组中寻找第i位数。有T(n) = T(n) + T(max(k, n-k)) + O(n),T(n) = T(n) and T(n) >= T(max(k, n-k))。所有问题的关键在于缩小问题的规模使得等式右边的第一个T(n)变为T(x),x<n,且取得k划分使得T(n) > T(x) + T(max(k, n-k)) + O(n),
def PARTITION_BYVALUE(A, p, r, value):
flag = p
i = p
for j in range(p, r+1):
if A[j] <= value:
temp = A[i]
A[i] = A[j]
A[j] = temp
if A[i] == value:
flag = i
i = i + 1
if i > flag:
temp = A[i-1]
A[i-1] = A[flag]
A[flag] = temp
return i-1
def INSERTION_SORT(A):
for j in range(1, len(A)):
key = A[j]
i = j - 1
while i >= 0 and A[i] > key:
A[i + 1] = A[i]
i = i - 1
A[i + 1] = key
def SELECT(A, p, r, i):
if p == r:
return A[p]
B = []
midarray = []
for j in range(p, r+1, 5):
if j+5 > r:
B.append(A[j:r+1])
else:
B.append(A[j:j+5])
INSERTION_SORT(B[len(B)-1])
midarray.append(B[len(B)-1][len(B[len(B)-1])//2])
mid = SELECT(midarray, 0, len(midarray)-1, len(midarray)//2)
q = PARTITION_BYVALUE(A, p, r, mid)
assert(A[q] == mid)
k = q-p+1
if i == k:
return A[q]
elif i < k:
return SELECT(A, p, q-1, i)
else:
return SELECT(A, q+1, r, i-k)