Skip to content
Closed
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
65 changes: 47 additions & 18 deletions sorts/quick_sort.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,75 @@
For manual testing run:
python3 quick_sort.py
"""

from __future__ import annotations

from random import randrange


def quick_sort(collection: list) -> list:
"""A pure Python implementation of quicksort algorithm.
"""A pure Python implementation of quicksort algorithm using in-place sorting.

:param collection: a mutable collection of comparable items
:return: the same collection ordered in ascending order

Examples:
>>> quick_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]

>>> quick_sort([])
[]

>>> quick_sort([-2, 5, 0, -45])
[-45, -2, 0, 5]
"""
# Base case: if the collection has 0 or 1 elements, it is already sorted
if len(collection) < 2:
return collection
# Call the helper function to sort in-place
_quick_sort(collection, 0, len(collection) - 1)
return collection


def _quick_sort(collection: list, low: int, high: int) -> None:
"""Helper function that performs in-place quicksort.

:param collection: the list to sort
:param low: starting index of the partition
:param high: ending index of the partition
"""
if low < high:
# Partition the array and get the pivot index
pivot_index = _partition(collection, low, high)
# Recursively sort elements before and after partition
_quick_sort(collection, low, pivot_index - 1)
_quick_sort(collection, pivot_index + 1, high)


def _partition(collection: list, low: int, high: int) -> int:
"""In-place partitioning using Lomuto partition scheme.

:param collection: the list to partition
:param low: starting index of the partition
:param high: ending index of the partition
:return: the final pivot index after partitioning
"""
# Randomly select a pivot index and swap with the last element
pivot_index = randrange(low, high + 1)
collection[pivot_index], collection[high] = collection[high], collection[pivot_index]

Check failure on line 61 in sorts/quick_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

sorts/quick_sort.py:61:89: E501 Line too long (89 > 88)
pivot = collection[high]

# Randomly select a pivot index and remove the pivot element from the collection
pivot_index = randrange(len(collection))
pivot = collection.pop(pivot_index)
# Index of smaller element (elements <= pivot will be moved to left of this)
i = low - 1

# Partition the remaining elements into two groups: lesser or equal, and greater
lesser = [item for item in collection if item <= pivot]
greater = [item for item in collection if item > pivot]
# Traverse through all elements and move smaller elements to the left
for j in range(low, high):
if collection[j] <= pivot:
i += 1
collection[i], collection[j] = collection[j], collection[i]

# Recursively sort the lesser and greater groups, and combine with the pivot
return [*quick_sort(lesser), pivot, *quick_sort(greater)]
# Place pivot in its correct position
collection[i + 1], collection[high] = collection[high], collection[i + 1]
return i + 1


if __name__ == "__main__":
# Get user input and convert it into a list of integers
user_input = input("Enter numbers separated by a comma:\n").strip()
unsorted = [int(item) for item in user_input.split(",")]
import doctest

# Print the result of sorting the user-provided list
print(quick_sort(unsorted))
doctest.testmod()
Loading