本章討論從乙個由n個互異的元素構成的集合中選擇第i個順序統計量的問題,提出了順序統計量、中位數(上中位數、下中位數)的概念,討論了從乙個集合中選擇最小元素和最大元素的問題,並分析討論了兩種選擇問題的演算法。
第i個順序統計量:在由n個元素組成的集合中,第i小的元素,如最小值為第1個順序統計量,最大值為第n個順序統計量
中位數:集合中的「中點元素」
下中位數:
上中位數:
從乙個有n個元素的集合中,找出其最大元素與最小元素。
若分別找出最大值與最小值,總共需進行n-1次比較;若同時找出最大值與最小值,最多需
這是一種解決選擇問題的分治演算法,以快速排序演算法為模型,對輸入陣列進行遞迴劃分,但只處理劃分的一邊。其在元素互異的假設條件下可達到o(n)的期望執行時間。
演算法**實現如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
defpartition
(a, p, r)
: x = a[r]
i = p -
1for j in
range
(p, r)
:if a[j]
<= x:
i +=
1 tmp = a[i]
a[i]
= a[j]
a[j]
= tmp
tmp = a[i +1]
a[i +1]
= a[r]
a[r]
= tmp
return i +
1def
quick_sort
(a, p, r)
:if p < r:
q = partition(a, p, r)
quick_sort(a, p, q -1)
quick_sort(a, q +
1, r)
defrandomized_select
(a, p, r, i)
:if p == r:
return a[p]
q = partition(a, p, r)
k = q - p +
1if 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)
if __name__ ==
'__main__'
: a =[9
,3,5
,2,3
,5,7
,8,9
,1,11
,20,0
,2] b = a[:]
print
(a) quick_sort(a,0,
len(a)-1
)print
(a) selected =
9 i = randomized_select(b,0,
len(b)-1
, selected)
print
(i, a[selected -1]
)
對以上演算法進行修改,將劃分的祝願也作為輸入元素,在最壞情況下執行時間為o(n)。
演算法**實現如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import random
import math
sublen =
5midsub =
2def
select_insertion_sort
(a, start, end)
:for j in
range
(start +
1, end +1,
1): key = a[j]
i = j -
1while i >= start and a[i]
> key:
a[i +1]
= a[i]
i = i -
1 a[i +1]
= key
defselect_partition
(a, p, r, x)
: i = p
for j in
range
(p, r +1)
:if a[j]
<= x:
tmp = a[i]
a[i]
= a[j]
a[j]
= tmp
i +=
1return i - p
defselect
(a, start, end, s)
:if end - start +
1<= sublen:
select_insertion_sort(a, start, end)
return a[start + s -1]
c = math.ceil(
(end - start +1)
/ sublen)
b =for i in
range(0
, c)
: e =
(i * start + sublen -1)
if(i * start + sublen -1)
<
(len
(a)-1)
else
(len
(a)-1)
select_insertion_sort(a, start + i * sublen, e)
midindex =
(start + i * sublen + midsub)
if(i < c -1)
else
int(
(start + i * sublen + end)/2
))b = select(b,0,
len(b)-1
, math.ceil(
len(b)/2
))k = select_partition(a, start, end, b)
if k == s:
return b
elif k > s:
return select(a, start, start + k -
1, s)
else
:return select(a, start + k, end, s - k)
if __name__ ==
'__main__'
: a =
[int
(random.random()*
1000
)for i in
range(0
,400)]
c = a[:]
a.sort(
) s =
117 value = select(c,0,
len(c)-1
, s)
print
(value, a[s -1]
)
演算法導論第九章 中位數和順序統計量
9.1 最小值和最大值 遍歷陣列,線性時間求最小值 int minimun int a 兩兩相比,3n 2次比較即可求最小值和最大值 void minandmax int a,int min,int max 如果n是偶數 else 成對地處理餘下的元素 for i length a i i 2 9....
演算法導論 第九章 中位數和順序統計量
def 第i個順序統計量,是該集合中第i小的元素。def 選擇問題 輸入,乙個包含n個數的集合a,和乙個整數i,1 i n。輸出,元素x屬於a,且a中恰好有i 1個其他元素小於它。9.1 最大值和最小值 尋找乙個陣列中的最大值和最小值需要經過n 1次比較找到 def minimum a mini a...
《演算法導論》筆記系列之第九章中位數和順序統計量
在乙個由n個元素組成的集合中,第i個順序統計量,是該集合中第i小的元素。9.1討論了陣列的最小值和最大值。如果要找出陣列的最小值,可以通過至多n 1次比較得出。最大值相同。但若要求同時找出最大值和最小值呢?可以採用9.1介紹的方法。就是不是將元素與最小值或最大值相比,而是將陣列的元素成對處理,先將兩...