forked from yidao620c/core-algorithm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathat209_imin_select2.py
More file actions
77 lines (66 loc) · 2.13 KB
/
at209_imin_select2.py
File metadata and controls
77 lines (66 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# 顺序统计量的选择算法(最坏情况下O(n))
"""
Topic: sample
Desc : 顺序统计量的选择算法(最坏情况下O(n))
利用中位数的中位数作为pivot划分数组
"""
from ch02_sort.at103_insert_sort import insertSort
__author__ = 'Xiong Neng'
def iminSelect2(A, i):
"""
返回数组A中第i小的元素,返回结果也就是A从小到大排序后第i个元素
"""
return __iminSelect2(A, 0, len(A) - 1, i)
def __iminSelect2(A, p, r, nn):
"""
返回数组A[p..r]中第i小的元素
利用中位数的中位数作为pivot划分数组
"""
if p == r:
return A[p]
midOfMid = __selectMidOfMid(A[p: r + 1])
midIndex = p
for i in range(p, r + 1):
if A[i] == midOfMid:
midIndex = i
break
q = __midPartition(A, p, r, midIndex)
k = q - p + 1
if nn == k:
return A[q]
elif nn < k:
return __iminSelect2(A, p, q - 1, nn)
else:
return __iminSelect2(A, q + 1, r, nn - k)
def __selectMidOfMid(seq):
"""获取中位数的中位数算法"""
while len(seq) > 1:
grpNum, lastNum = divmod(len(seq), 5) # 分组,每组5个
midArr = [] # 每组的中位数列表
for i in range(0, grpNum):
eachGroup = seq[i * 5: (i + 1) * 5]
insertSort(eachGroup)
midArr.append(eachGroup[2])
if lastNum > 0:
lastGroup = seq[grpNum * 5: grpNum * 5 + lastNum]
insertSort(lastGroup)
midArr.append(lastGroup[(lastNum - 1) // 2])
seq = midArr
return seq[0]
def __midPartition(A, p, r, midIndex):
"""分解子数组: 中位数作为pivot的版本"""
A[midIndex], A[r] = A[r], A[midIndex] # 还是将这个pivot放到最后
x = A[r]
i = p - 1
for j in range(p, r):
if A[j] <= x:
i += 1
A[i], A[j] = A[j], A[i]
A[i + 1], A[r] = A[r], A[i + 1]
return i + 1
if __name__ == '__main__':
bb = [4, 23, 65, 3, 22, 3, 34, 3, 67, 3, 12, 3, 7, 1, 1, 256, 3, 34, 27]
print(sorted(bb))
print(iminSelect2(bb, 10))