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)