Skip to content

Commit 2e7649b

Browse files
committed
added median of medians algorithms for searching
1 parent b76115e commit 2e7649b

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

Diff for: searches/median_of_medians.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""
2+
A Python implementation of the Median of Medians algorithm to select pivots for QuickSelect,
3+
which is efficient for calculating the value that would appear in the index of a list if it
4+
would be sorted, even if it is not already sorted. Search in time complexity O(n) at any rank
5+
deterministically
6+
https://en.wikipedia.org/wiki/Median_of_medians
7+
"""
8+
9+
def MedianofFive(arr:list) -> int:
10+
"""
11+
Return the median of the input list
12+
:param arr: Array to find median of
13+
:return: median of arr
14+
"""
15+
arr=sorted(arr)
16+
return arr[len(arr)//2]
17+
18+
def MedianofMedians(arr:list) -> int:
19+
"""
20+
Return a pivot to partition data on by calculating
21+
Median of medians of input data
22+
:param arr: The data to be sorted (a list)
23+
:param k: The rank to be searched
24+
:return: element at rank k
25+
"""
26+
if len(arr) <= 5: return MedianofFive(arr)
27+
medians = []
28+
i=0
29+
while i<len(arr):
30+
if (i + 4) <= len(arr): medians.append(MedianofFive(arr[i:].copy()))
31+
else: medians.append(MedianofFive(arr[i:i+5].copy()))
32+
i+=5
33+
return MedianofMedians(medians)
34+
35+
def QuickSelect(arr:list, k:int) -> int:
36+
"""
37+
>>> QuickSelect([2, 4, 5, 7, 899, 54, 32], 5)
38+
32
39+
>>> QuickSelect([2, 4, 5, 7, 899, 54, 32], 1)
40+
2
41+
>>> QuickSelect([5, 4, 3, 2], 2)
42+
3
43+
>>> QuickSelect([3, 5, 7, 10, 2, 12], 3)
44+
5
45+
"""
46+
47+
"""
48+
Two way partition the data into smaller and greater lists,
49+
in relationship to the pivot
50+
:param arr: The data to be sorted (a list)
51+
:param k: The rank to be searched
52+
:return: element at rank k
53+
"""
54+
55+
# Invalid Input
56+
if k>len(arr):
57+
return None
58+
59+
# x is the estimated pivot by median of medians algorithm
60+
x = MedianofMedians(arr)
61+
left = []
62+
right = []
63+
check = False
64+
smaller = 0
65+
for i in range(len(arr)):
66+
if arr[i] < x:
67+
left.append(arr[i])
68+
elif arr[i] > x:
69+
right.append(arr[i])
70+
elif arr[i] == x and not check:
71+
check = True
72+
else:
73+
right.append(arr[i])
74+
rankX = len(left) + 1
75+
if(rankX==k): answer = x
76+
elif rankX>k: answer = QuickSelect(left,k)
77+
elif rankX<k: answer = QuickSelect(right,k-rankX)
78+
return answer;

0 commit comments

Comments
 (0)