I'm working on a problem to sort array by low, medium and high -- in-place tweak original array. I'm looking for advice, especially any algorithm implementation efficiency. My current bottleneck of implementation is that I have to do partition twice, by low+medium and high, then do low and medium partition on low+medium part. I'd like to do partition only once.
'''
You have an unsorted array of integers and a
function........string getCategory(integer)........
which deterministically returns 1 of three possible strings:
"low", "medium", or "high", depending on the input integer.
You need to output an array with all the "low" numbers at the bottom,
all the "medium" numbers in the middle, and all the "high" numbers at the top.
This is basically a partial sort. Within each category, the order of the numbers does not matter...
For example, you might be give the array [5,7,2,9,1,14,12,10,5,3].
For input integers 1 - 3, getCategory(integer) returns "low",
for 4 - 10 it returns "medium," and for 11 - 15 it returns "high".
You could output an array (or modify the given array) that looks like this: [3,1,2,5,5,9,7,10,14,12]
'''
def getCategory(value):
if 1<=value<=3:
return 'low'
elif 4<=value<=10:
return 'medium'
else:
return 'high'
def partial_sort(numbers):
low_and_medium_index = 0
high_index = len(numbers)-1
while low_and_medium_index <= high_index:
while low_and_medium_index <= high_index and \
getCategory(numbers[low_and_medium_index]) != 'high':
low_and_medium_index+=1
while low_and_medium_index <= high_index and \
getCategory(numbers[high_index]) == 'high':
high_index -= 1
if low_and_medium_index < high_index:
numbers[low_and_medium_index], numbers[high_index] = numbers[high_index], numbers[low_and_medium_index]
else:
break
low_index = 0
medium_index = low_and_medium_index - 1
while low_index <= medium_index:
while low_index <= medium_index and \
getCategory(numbers[low_index]) == 'low':
low_index+=1
while low_index <= medium_index and \
getCategory(numbers[medium_index]) == 'medium':
medium_index -= 1
if low_index < medium_index:
numbers[low_index], numbers[medium_index] = numbers[medium_index], numbers[low_index]
else:
break
return numbers
if __name__ == "__main__":
print partial_sort([5,7,2,9,1,14,12,10,5,3])
list.sort
here? Even for large data it should be able to outperform pure Python approaches. \$\endgroup\$