From 1958cf25c5e636e695a7cbed529a013f3a4704cd Mon Sep 17 00:00:00 2001 From: theycallmemac Date: Thu, 28 Sep 2017 20:54:15 +0100 Subject: [PATCH 1/2] added timsort.py --- sorts/timsort.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 sorts/timsort.py diff --git a/sorts/timsort.py b/sorts/timsort.py new file mode 100644 index 000000000..04360e256 --- /dev/null +++ b/sorts/timsort.py @@ -0,0 +1,68 @@ +def binary_search(the_array, item, start, end): + if start == end: + if the_array[start] > item: + return start + else: + return start + 1 + if start > end: + return start + + mid = (start + end)/ 2 + if the_array[mid] < item: + return binary_search(the_array, item, mid + 1, end) + elif the_array[mid] > item: + return binary_search(the_array, item, start, mid - 1) + else: + return mid + + +""" +Insertion sort that the heap sort uses if the array size is small or if +the size of the "run" is small +""" +def insertion_sort(the_array): + l = len(the_array) + for index in range(1, l): + value = the_array[index] + pos = binary_search(the_array, value, 0, index - 1) + the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:] + return the_array + +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: + return right + if not right: + return left + if left[0] < right[0]: + return [left[0]] + merge(left[1:], right) + return [right[0]] + merge(left, right[1:]) + + +def timsort(the_array): + runs, sorted_runs = [], [] + l = len(the_array) + new_run = [the_array[0]] + for i in range(1, l): + if i == l-1: + new_run.append(the_array[i]) + runs.append(new_run) + break + if the_array[i] < the_array[i-1]: + if not new_run: + runs.append([the_array[i-1]]) + new_run.append(the_array[i]) + else: + runs.append(new_run) + new_run = [] + else: + new_run.append(the_array[i]) + for each in runs: + sorted_runs.append(insertion_sort(each)) + sorted_array = [] + for run in sorted_runs: + sorted_array = merge(sorted_array, run) +print(sorted_array) From a97ab2f4e433e41a38fd28307a02f412c4fb3a01 Mon Sep 17 00:00:00 2001 From: James Mc Dermott Date: Sun, 1 Oct 2017 22:13:54 +0100 Subject: [PATCH 2/2] Update timsort.py --- sorts/timsort.py | 85 ++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/sorts/timsort.py b/sorts/timsort.py index 04360e256..8c75b5191 100644 --- a/sorts/timsort.py +++ b/sorts/timsort.py @@ -1,68 +1,81 @@ -def binary_search(the_array, item, start, end): +def binary_search(lst, item, start, end): if start == end: - if the_array[start] > item: + if lst[start] > item: return start else: return start + 1 if start > end: return start - mid = (start + end)/ 2 - if the_array[mid] < item: - return binary_search(the_array, item, mid + 1, end) - elif the_array[mid] > item: - return binary_search(the_array, item, start, mid - 1) + 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) else: return mid -""" -Insertion sort that the heap sort uses if the array size is small or if -the size of the "run" is small -""" -def insertion_sort(the_array): - l = len(the_array) - for index in range(1, l): - value = the_array[index] - pos = binary_search(the_array, value, 0, index - 1) - the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:] - return the_array +def insertion_sort(lst): + length = len(lst) + + for index in range(1, length): + value = lst[index] + pos = binary_search(lst, value, 0, index - 1) + lst = lst[:pos] + [value] + lst[pos:index] + lst[index+1:] + + return lst + 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: return right + if not right: return left + if left[0] < right[0]: return [left[0]] + merge(left[1:], right) + return [right[0]] + merge(left, right[1:]) -def timsort(the_array): +def timsort(lst): runs, sorted_runs = [], [] - l = len(the_array) - new_run = [the_array[0]] - for i in range(1, l): - if i == l-1: - new_run.append(the_array[i]) + length = len(lst) + new_run = [lst[0]] + sorted_array = [] + + for i in range(1, length): + if i == length - 1: + new_run.append(lst[i]) runs.append(new_run) break - if the_array[i] < the_array[i-1]: + + if lst[i] < lst[i - 1]: if not new_run: - runs.append([the_array[i-1]]) - new_run.append(the_array[i]) + runs.append([lst[i - 1]]) + new_run.append(lst[i]) else: runs.append(new_run) new_run = [] else: - new_run.append(the_array[i]) - for each in runs: - sorted_runs.append(insertion_sort(each)) - sorted_array = [] + new_run.append(lst[i]) + + for run in runs: + sorted_runs.append(insertion_sort(run)) + for run in sorted_runs: 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()