Update timsort.py

This commit is contained in:
James Mc Dermott 2017-10-01 22:13:54 +01:00 committed by GitHub
parent 1958cf25c5
commit a97ab2f4e4

View File

@ -1,68 +1,81 @@
def binary_search(the_array, item, start, end): def binary_search(lst, item, start, end):
if start == end: if start == end:
if the_array[start] > item: if lst[start] > item:
return start return start
else: else:
return start + 1 return start + 1
if start > end: if start > end:
return start return start
mid = (start + end)/ 2 mid = (start + end) // 2
if the_array[mid] < item: if lst[mid] < item:
return binary_search(the_array, item, mid + 1, end) return binary_search(lst, item, mid + 1, end)
elif the_array[mid] > item: elif lst[mid] > item:
return binary_search(the_array, item, start, mid - 1) return binary_search(lst, item, start, mid - 1)
else: else:
return mid return mid
""" def insertion_sort(lst):
Insertion sort that the heap sort uses if the array size is small or if length = len(lst)
the size of the "run" is small
""" for index in range(1, length):
def insertion_sort(the_array): value = lst[index]
l = len(the_array) pos = binary_search(lst, value, 0, index - 1)
for index in range(1, l): lst = lst[:pos] + [value] + lst[pos:index] + lst[index+1:]
value = the_array[index]
pos = binary_search(the_array, value, 0, index - 1) return lst
the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:]
return the_array
def merge(left, right): def merge(left, right):
"""Takes two sorted lists and returns a single sorted list by comparing the
elements one at a time.
[1, 2, 3, 4, 5, 6]
"""
if not left: if not left:
return right return right
if not right: if not right:
return left return left
if left[0] < right[0]: if left[0] < right[0]:
return [left[0]] + merge(left[1:], right) return [left[0]] + merge(left[1:], right)
return [right[0]] + merge(left, right[1:]) return [right[0]] + merge(left, right[1:])
def timsort(the_array): def timsort(lst):
runs, sorted_runs = [], [] runs, sorted_runs = [], []
l = len(the_array) length = len(lst)
new_run = [the_array[0]] new_run = [lst[0]]
for i in range(1, l): sorted_array = []
if i == l-1:
new_run.append(the_array[i]) for i in range(1, length):
if i == length - 1:
new_run.append(lst[i])
runs.append(new_run) runs.append(new_run)
break break
if the_array[i] < the_array[i-1]:
if lst[i] < lst[i - 1]:
if not new_run: if not new_run:
runs.append([the_array[i-1]]) runs.append([lst[i - 1]])
new_run.append(the_array[i]) new_run.append(lst[i])
else: else:
runs.append(new_run) runs.append(new_run)
new_run = [] new_run = []
else: else:
new_run.append(the_array[i]) new_run.append(lst[i])
for each in runs:
sorted_runs.append(insertion_sort(each)) for run in runs:
sorted_array = [] sorted_runs.append(insertion_sort(run))
for run in sorted_runs: for run in sorted_runs:
sorted_array = merge(sorted_array, run) sorted_array = merge(sorted_array, run)
print(sorted_array)
return sorted_array
def main():
lst = [5,9,10,3,-4,5,178,92,46,-18,0,7]
sorted_lst = timsort(lst)
print(sorted_lst)
if __name__ == '__main__':
main()