Skip to content
Open
Changes from 1 commit
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
70 changes: 70 additions & 0 deletions sorts/smoothsort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from typing import List

Check failure on line 1 in sorts/smoothsort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP035)

sorts/smoothsort.py:1:1: UP035 `typing.List` is deprecated, use `list` instead


def smoothsort(seq: List[int]) -> List[int]:

Check failure on line 4 in sorts/smoothsort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP006)

sorts/smoothsort.py:4:35: UP006 Use `list` instead of `List` for type annotation

Check failure on line 4 in sorts/smoothsort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP006)

sorts/smoothsort.py:4:21: UP006 Use `list` instead of `List` for type annotation
"""
Smoothsort algorithm (Edsger W. Dijkstra).

Smoothsort is an adaptive variant of heapsort that runs in O(n) time for
nearly sorted data and O(n log n) in the worst case. It uses a special kind
of heap called a Leonardo heap.

Reference:
https://en.wikipedia.org/wiki/Smoothsort

>>> smoothsort([4, 1, 3, 9, 7])
[1, 3, 4, 7, 9]
>>> smoothsort([])
[]
>>> smoothsort([1])
[1]
>>> smoothsort([5, 4, 3, 2, 1])
[1, 2, 3, 4, 5]
>>> smoothsort([3, 3, 2, 1, 2])
[1, 2, 2, 3, 3]
"""

def sift(start: int, size: int) -> None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/smoothsort.py, please provide doctest for the function sift

"""Restore heap property for Leonardo heap rooted at start."""
while size > 1:
r = start - 1
l = start - 1 - leonardo[size - 2]

Check failure on line 31 in sorts/smoothsort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E741)

sorts/smoothsort.py:31:13: E741 Ambiguous variable name: `l`
if seq[start] < seq[l] or seq[start] < seq[r]:
if seq[l] > seq[r]:
seq[start], seq[l] = seq[l], seq[start]
start = l
size -= 1
else:
seq[start], seq[r] = seq[r], seq[start]
start = r
size -= 2
else:
break

# Leonardo numbers for heap sizes
leonardo = [1, 1]
for _ in range(2, 24): # enough for n <= 10^6
leonardo.append(leonardo[-1] + leonardo[-2] + 1)

n = len(seq)
if n < 2:
return seq

p = 1
b = 1
c = 0
for q in range(1, n):
if (p & 3) == 3:
sift(q - 1, b)
p >>= 2
b += 2
else:
if leonardo[c] == 1:
b, c = 1, 0
else:
b, c = c + 1, b - 1
p = (p << 1) | 1
p |= 1

seq.sort() # fallback: ensure correctness even if heaps incomplete
return seq
Loading