Skip to content

Fix Tree Sort algorithm for duplicate values and input types #12786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
Next Next commit
fix tree_sort.py
  • Loading branch information
lighting9999 authored Jun 7, 2025
commit c29a1e0a3e50a41ee7b5a8a6378092a10c5a4227
90 changes: 50 additions & 40 deletions sorts/tree_sort.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,82 @@
"""
Tree_sort algorithm.

Build a Binary Search Tree and then iterate thru it to get a sorted list.
"""

from __future__ import annotations

from collections.abc import Iterator
from dataclasses import dataclass

Check failure on line 3 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

sorts/tree_sort.py:1:1: I001 Import block is un-sorted or un-formatted


@dataclass
class Node:
"""Node of a Binary Search Tree (BST) for sorting."""
val: int
left: Node | None = None
right: Node | None = None

def __iter__(self) -> Iterator[int]:
"""In-order traversal generator for BST."""
# Traverse left subtree first (smaller values)
if self.left:
yield from self.left

Check failure on line 17 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:17:1: W293 Blank line contains whitespace
# Current node value
yield self.val

Check failure on line 20 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:20:1: W293 Blank line contains whitespace
# Traverse right subtree last (larger values)
if self.right:
yield from self.right

def __len__(self) -> int:
return sum(1 for _ in self)

def insert(self, val: int) -> None:
if val < self.val:
"""Insert value into BST while maintaining sort order."""
# Values <= current go to left subtree
if val <= self.val:
if self.left is None:
self.left = Node(val)
else:
self.left.insert(val)
elif val > self.val:
# Values > current go to right subtree
else:
if self.right is None:

Check failure on line 35 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR5501)

sorts/tree_sort.py:34:9: PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
self.right = Node(val)
else:
self.right.insert(val)


def tree_sort(arr: list[int]) -> tuple[int, ...]:
def tree_sort(arr: list[int] | tuple[int, ...]) -> tuple[int, ...]:
"""
>>> tree_sort([])
()
>>> tree_sort((1,))
(1,)
>>> tree_sort((1, 2))
(1, 2)
>>> tree_sort([5, 2, 7])
(2, 5, 7)
>>> tree_sort((5, -4, 9, 2, 7))
(-4, 2, 5, 7, 9)
>>> tree_sort([5, 6, 1, -1, 4, 37, 2, 7])
(-1, 1, 2, 4, 5, 6, 7, 37)

# >>> tree_sort(range(10, -10, -1)) == tuple(sorted(range(10, -10, -1)))
# True
Sort sequence using Binary Search Tree (BST) traversal.

Check failure on line 44 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:44:1: W293 Blank line contains whitespace
Args:
arr: Input sequence (list or tuple of integers)

Check failure on line 47 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:47:1: W293 Blank line contains whitespace
Returns:
Tuple of sorted integers

Check failure on line 50 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:50:1: W293 Blank line contains whitespace
Examples:
>>> tree_sort([])
()
>>> tree_sort((1,))
(1,)
>>> tree_sort((1, 2))
(1, 2)
>>> tree_sort([5, 2, 7])
(2, 5, 7)
>>> tree_sort((5, -4, 9, 2, 7))
(-4, 2, 5, 7, 9)
>>> tree_sort([5, 6, 1, -1, 4, 37, 2, 7])
(-1, 1, 2, 4, 5, 6, 7, 37)
>>> tree_sort([5, 2, 7, 5]) # Test duplicate handling
(2, 5, 5, 7)
"""
if len(arr) == 0:
return tuple(arr)
root = Node(arr[0])
for item in arr[1:]:
# Handle empty input immediately
if not arr:
return ()

Check failure on line 70 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:70:1: W293 Blank line contains whitespace
# Convert to list for uniform processing
items = list(arr)

Check failure on line 73 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:73:1: W293 Blank line contains whitespace
# Initialize BST root with first element
root = Node(items[0])

Check failure on line 76 in sorts/tree_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/tree_sort.py:76:1: W293 Blank line contains whitespace
# Insert remaining items into BST
for item in items[1:]:
root.insert(item)

# Convert BST traversal to sorted tuple
return tuple(root)


if __name__ == "__main__":
import doctest

doctest.testmod()
print(f"{tree_sort([5, 6, 1, -1, 4, 37, -3, 7]) = }")