2017-10-01 21:13:54 +00:00
|
|
|
def binary_search(lst, item, start, end):
|
2017-09-28 19:54:15 +00:00
|
|
|
if start == end:
|
2019-07-30 16:06:48 +00:00
|
|
|
return start if lst[start] > item else start + 1
|
2017-09-28 19:54:15 +00:00
|
|
|
if start > end:
|
|
|
|
return start
|
|
|
|
|
2017-10-01 21:13:54 +00:00
|
|
|
mid = (start + end) // 2
|
|
|
|
if lst[mid] < item:
|
|
|
|
return binary_search(lst, item, mid + 1, end)
|
|
|
|
elif lst[mid] > item:
|
|
|
|
return binary_search(lst, item, start, mid - 1)
|
2017-09-28 19:54:15 +00:00
|
|
|
else:
|
|
|
|
return mid
|
|
|
|
|
|
|
|
|
2017-10-01 21:13:54 +00:00
|
|
|
def insertion_sort(lst):
|
|
|
|
length = len(lst)
|
|
|
|
|
|
|
|
for index in range(1, length):
|
|
|
|
value = lst[index]
|
|
|
|
pos = binary_search(lst, value, 0, index - 1)
|
2019-07-30 16:06:48 +00:00
|
|
|
lst = lst[:pos] + [value] + lst[pos:index] + lst[index + 1 :]
|
2017-10-01 21:13:54 +00:00
|
|
|
|
|
|
|
return lst
|
|
|
|
|
2017-09-28 19:54:15 +00:00
|
|
|
|
|
|
|
def merge(left, right):
|
|
|
|
if not left:
|
|
|
|
return right
|
2017-10-01 21:13:54 +00:00
|
|
|
|
2017-09-28 19:54:15 +00:00
|
|
|
if not right:
|
|
|
|
return left
|
2017-10-01 21:13:54 +00:00
|
|
|
|
2017-09-28 19:54:15 +00:00
|
|
|
if left[0] < right[0]:
|
|
|
|
return [left[0]] + merge(left[1:], right)
|
2017-10-01 21:13:54 +00:00
|
|
|
|
2017-09-28 19:54:15 +00:00
|
|
|
return [right[0]] + merge(left, right[1:])
|
|
|
|
|
|
|
|
|
2019-05-25 13:41:24 +00:00
|
|
|
def tim_sort(lst):
|
2019-07-30 16:06:48 +00:00
|
|
|
"""
|
|
|
|
>>> tim_sort("Python")
|
|
|
|
['P', 'h', 'n', 'o', 't', 'y']
|
|
|
|
>>> tim_sort((1.1, 1, 0, -1, -1.1))
|
|
|
|
[-1.1, -1, 0, 1, 1.1]
|
|
|
|
>>> tim_sort(list(reversed(list(range(7)))))
|
|
|
|
[0, 1, 2, 3, 4, 5, 6]
|
|
|
|
>>> tim_sort([3, 2, 1]) == insertion_sort([3, 2, 1])
|
|
|
|
True
|
|
|
|
>>> tim_sort([3, 2, 1]) == sorted([3, 2, 1])
|
|
|
|
True
|
|
|
|
"""
|
2017-10-01 21:13:54 +00:00
|
|
|
length = len(lst)
|
2019-07-30 16:06:48 +00:00
|
|
|
runs, sorted_runs = [], []
|
2017-10-01 21:13:54 +00:00
|
|
|
new_run = [lst[0]]
|
|
|
|
sorted_array = []
|
2019-07-30 16:06:48 +00:00
|
|
|
i = 1
|
|
|
|
while i < length:
|
2017-10-01 21:13:54 +00:00
|
|
|
if lst[i] < lst[i - 1]:
|
2019-07-30 16:06:48 +00:00
|
|
|
runs.append(new_run)
|
|
|
|
new_run = [lst[i]]
|
2017-09-28 19:54:15 +00:00
|
|
|
else:
|
2017-10-01 21:13:54 +00:00
|
|
|
new_run.append(lst[i])
|
2019-07-30 16:06:48 +00:00
|
|
|
i += 1
|
|
|
|
runs.append(new_run)
|
2017-10-01 21:13:54 +00:00
|
|
|
|
|
|
|
for run in runs:
|
|
|
|
sorted_runs.append(insertion_sort(run))
|
2017-09-28 19:54:15 +00:00
|
|
|
for run in sorted_runs:
|
|
|
|
sorted_array = merge(sorted_array, run)
|
2017-10-01 21:13:54 +00:00
|
|
|
|
|
|
|
return sorted_array
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
2019-07-30 16:06:48 +00:00
|
|
|
lst = [5, 9, 10, 3, -4, 5, 178, 92, 46, -18, 0, 7]
|
2019-05-25 13:41:24 +00:00
|
|
|
sorted_lst = tim_sort(lst)
|
2017-10-01 21:13:54 +00:00
|
|
|
print(sorted_lst)
|
|
|
|
|
2019-07-30 16:06:48 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2017-10-01 21:13:54 +00:00
|
|
|
main()
|