Skip to content
Back to skills

Algo Binary Search Trees

ASecurity

BST operations, complexity, and a clean implementation with parent pointers supporting all standard operations.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
data-aipythongonode

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add Pavel-Kravchenko/Bioinformatics --skill algo-binary-search-trees --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Algo Binary Search Trees?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Algo Binary Search Trees
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pavel-kravchenko-algo-binary-search-trees/badge)](https://www.skillsdirectory.com/skills/pavel-kravchenko-algo-binary-search-trees)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: algo-binary-search-trees
description: "BST operations, complexity, and a clean implementation with parent pointers supporting all standard operations."
tool_type: python
primary_tool: Python
---

# Binary Search Trees (BST)

**Invariant**: left subtree < node < right subtree (no duplicates).

## Complexity

| Operation | Average | Worst (degenerate) |
|-----------|---------|-------------------|
| Search / Insert / Delete | O(log n) | O(n) |
| Min / Max | O(log n) | O(n) |
| Successor / Predecessor | O(log n) | O(n) |
| Inorder traversal | O(n) | O(n) |

Worst case occurs on sorted input — use AVL or Red-Black tree to guarantee O(log n).

## Implementation

```python
from collections import deque
from typing import Any

class Node:
    def __init__(self, value: Any) -> None:
        self.value = value
        self.left = self.right = self.parent = None


class BST:
    def __init__(self) -> None:
        self.root: Node | None = None

    # --- Insert (iterative) ---
    def insert(self, value: Any) -> Node:
        if not self.root:
            self.root = Node(value)
            return self.root
        node = self.root
        while True:
            if value < node.value:
                if node.left is None:
                    node.left = Node(value)
                    node.left.parent = node
                    return node.left
                node = node.left
            elif value > node.value:
                if node.right is None:
                    node.right = Node(value)
                    node.right.parent = node
                    return node.right
                node = node.right
            else:
                return node  # duplicate

    # --- Search (iterative) ---
    def search(self, value: Any) -> Node | None:
        node = self.root
        while node:
            if value == node.value:
                return node
            node = node.left if value < node.value else node.right
        return None

    # --- Min / Max ---
    def find_min(self, node: Node | None = None) -> Node | None:
        node = node or self.root
        if not node:
            return None
        while node.left:
            node = node.left
        return node

    def find_max(self, node: Node | None = None) -> Node | None:
        node = node or self.root
        if not node:
            return None
        while node.right:
            node = node.right
        return node

    # --- Successor / Predecessor ---
    def successor(self, node: Node) -> Node | None:
        if node.right:
            return self.find_min(node.right)
        p = node.parent
        while p and node == p.right:
            node, p = p, p.parent
        return p

    def predecessor(self, node: Node) -> Node | None:
        if node.left:
            return self.find_max(node.left)
        p = node.parent
        while p and node == p.left:
            node, p = p, p.parent
        return p

    # --- Delete ---
    def delete(self, value: Any) -> bool:
        node = self.search(value)
        if not node:
            return False
        self._delete_node(node)
        return True

    def _delete_node(self, node: Node) -> None:
        if node.left and node.right:
            succ = self.find_min(node.right)
            node.value = succ.value
            self._delete_node(succ)
        else:
            child = node.left or node.right
            self._transplant(node, child)

    def _transplant(self, u: Node, v: Node | None) -> None:
        if not u.parent:
            self.root = v
        elif u == u.parent.left:
            u.parent.left = v
        else:
            u.parent.right = v
        if v:
            v.parent = u.parent

    # --- Traversals ---
    def inorder(self) -> list[Any]:
        result: list[Any] = []
        def _rec(n):
            if n:
                _rec(n.left); result.append(n.value); _rec(n.right)
        _rec(self.root)
        return result

    def level_order(self) -> list[Any]:
        if not self.root:
            return []
        result, q = [], deque([self.root])
        while q:
            n = q.popleft()
            result.append(n.value)
            if n.left: q.append(n.left)
            if n.right: q.append(n.right)
        return result

    def __contains__(self, value: Any) -> bool:
        return self.search(value) is not None
```

## Delete: Three Cases

| Node type | Action |
|-----------|--------|
| Leaf | Remove directly |
| One child | Replace node with that child |
| Two children | Copy inorder successor's value, delete successor (which has at most one child) |

## Pitfalls

- **Sorted input degenerates to O(n)**: inserting [1,2,3,4,5] creates a linked list; use a self-balancing tree (AVL, Red-Black) for production use.
- **Inorder successor during deletion**: after copying the successor's value to the deleted node, you must delete the successor node — not the original node again.
- **Parent pointer consistency**: when implementing with parent pointers, update `v.parent` in `_transplant` only if `v` is not None.
- **Recursive height on deep trees**: Python's default recursion limit (~1000) is hit on degenerate trees; use iterative BFS for height calculation.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…