Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions prometheus/sorting_algorithms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
def tim_sort(array):
"""
Sorts an array using the Tim Sort algorithm.

:param array: The array to be sorted.
:type array: List[Union[int, float, str]]
:return: The sorted array.
:rtype: List[Union[int, float, str]]
"""
if len(array) < 2:
return array

# Minimum run size for small arrays
min_run = 32

# Divide the array into smaller chunks and recursively sort them
for i in range(0, len(array), min_run):
_tim_sort(array, i, min(i + min_run, len(array)))

# Merge the sorted chunks using binary search
for i in range(min_run, len(array), min_run):
left_index = _find_index_to_insert(array, i, i + min_run // 2)
right_index = _find_index_to_insert(array, left_index, i + min_run)
_merge(array, left_index, i + min_run // 2, right_index)


def _tim_sort(array, left, right):
"""
Recursively sorts a smaller chunk of the array using Tim Sort.

:param array: The array to be sorted.
:type array: List[Union[int, float, str]]
:param left: The left index of the chunk.
:type left: int
:param right: The right index of the chunk.
:type right: int
"""
if right - left < 2:
return

_tim_sort(array, left, (left + right) // 2)
_tim_sort(array, (left + right) // 2, right)

# Merge the sorted chunks using insertion sort for small arrays
if right - left == 2:
if array[left] > array[right - 1]:
array[left], array[right - 1] = array[right - 1], array[left]


def _find_index_to_insert(array, left, right):
"""
Finds the correct position to insert a value in a sorted chunk using binary search.

:param array: The array to be searched.
:type array: List[Union[int, float, str]]
:param left: The left index of the chunk.
:type left: int
:param right: The right index of the chunk.
:type right: int
:return: The index to insert the value.
:rtype: int
"""
while left < right:
mid = (left + right) // 2

if array[mid] >= array[right]:
right = mid
else:
left = mid + 1

return left


def _merge(array, left, mid, right):
"""
Merges two sorted chunks into a single sorted chunk.

:param array: The array to be merged.
:type array: List[Union[int, float, str]]
:param left: The left index of the first chunk.
:type left: int
:param mid: The middle index between the two chunks.
:type mid: int
:param right: The right index of the second chunk.
:type right: int
"""
temp = array[left:right]
left_index = left
right_index = mid

for i in range(left, right):
if left_index == mid:
array[i] = temp[right_index - mid]
right_index += 1
elif right_index == right or temp[left_index - left] <= temp[right_index - mid]:
array[i] = temp[left_index - left]
left_index += 1
else:
array[i] = temp[right_index - mid]
right_index += 1