diff --git a/README.md b/README.md index 182d36a8d905..728c36163636 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,54 @@ We are on [Discord](https://the-algorithms.com/discord) and [Gitter](https://git ## 📜 List of Algorithms See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project. + +## 🧩 Usage Example + +You can use this repository to explore and run algorithms locally on your system. + +###1️⃣ Clone the repository +```bash +git clone https://github.com/TheAlgorithms/Python.git +cd Python +### 2️⃣Run an algorithm example + +Pick any algorithm and run it using Python. +For example, to execute the binary search algorithm: + +python3 searches/binary_search.py + +###3️⃣ Using Python interactively + +You can also open an interactive shell: + +python3 +>>> from data_structures.binary_tree import splay_tree +>>> tree = splay_tree.SplayTree() +>>> tree.search(10) + +###To verify that all doctests in a file pass: + +python3 -m doctest -v data_structures/binary_tree/splay_tree.py + + +--- + +## 🧠 Why This Works + +✔️ Follows their Markdown and emoji style (`## 📜`, `## 🧩`) +✔️ Gives clear instructions for beginners +✔️ Matches issue #13714 (“Add Usage Example section to README”) +✔️ Maintains the tone and layout of the official README + +--- + +## 🚀 How to Commit and Push + +Once you add that section at the bottom of the README: + +```bash +git add README.md +git commit -m "Added 'Usage Example' section to README (fixes #13714)" +git push origin splaytree-v3 + + diff --git a/data_structures/binary_tree/splay_tree.py b/data_structures/binary_tree/splay_tree.py new file mode 100644 index 000000000000..e853eaffcc3f --- /dev/null +++ b/data_structures/binary_tree/splay_tree.py @@ -0,0 +1,151 @@ +""" +Splay Tree implementation in Python. + +A Splay Tree is a self-adjusting binary search tree where recently accessed +elements are moved closer to the root using rotations (splaying). +This improves access times for frequently used elements. + +Reference: https://en.wikipedia.org/wiki/Splay_tree +Author: yeshuawm999 +""" + +from __future__ import annotations + + +class Node: + """A node in the Splay Tree.""" + + def __init__( + self, + key: int, + parent: Node | None = None, + left: Node | None = None, + right: Node | None = None, + ) -> None: + self.key = key + self.parent = parent + self.left = left + self.right = right + + +class SplayTree: + """A self-adjusting Binary Search Tree (Splay Tree).""" + + def __init__(self) -> None: + self.root: Node | None = None + + # --- Basic Rotation Operations --- + + def _rotate_left(self, x: Node) -> None: + """Perform a left rotation around node x.""" + y = x.right + if not y: + return + x.right = y.left + if y.left: + y.left.parent = x + + y.parent = x.parent + if not x.parent: + self.root = y + elif x == x.parent.left: + x.parent.left = y + else: + x.parent.right = y + + y.left = x + x.parent = y + + def _rotate_right(self, x: Node) -> None: + """Perform a right rotation around node x.""" + y = x.left + if not y: + return + x.left = y.right + if y.right: + y.right.parent = x + + y.parent = x.parent + if not x.parent: + self.root = y + elif x == x.parent.right: + x.parent.right = y + else: + x.parent.left = y + + y.right = x + x.parent = y + + # --- Core Splay Operation --- + + def _splay(self, x: Node) -> None: + """Moves node x to the root of the tree using rotations.""" + while x.parent: + parent = x.parent + grandparent = parent.parent + + if not grandparent: + # Zig Case (x is a child of the root) + # One single rotation: + # Right if x is a left child, Left if x is a right child + if x == parent.left: + self._rotate_right(parent) + else: + self._rotate_left(parent) + elif x == parent.left and parent == grandparent.left: + # Zig-Zig (both left) + self._rotate_right(grandparent) + self._rotate_right(parent) + elif x == parent.right and parent == grandparent.right: + # Zig-Zig (both right) + self._rotate_left(grandparent) + self._rotate_left(parent) + elif x == parent.left and parent == grandparent.right: + # Zig-Zag (left-right) + self._rotate_right(parent) + self._rotate_left(grandparent) + else: + # Zig-Zag (right-left) + self._rotate_left(parent) + self._rotate_right(grandparent) + + # --- Search Method --- + + def search(self, key: int) -> bool: + """Search for a key. If found, splay it to the root.""" + current = self.root + found_node = None + while current: + if key == current.key: + found_node = current + break + current = current.left if key < current.key else current.right + + if found_node: + self._splay(found_node) + return True + return False + + +if __name__ == "__main__": + """ + Example run: + >>> tree = SplayTree() + >>> tree.root = Node(10) + >>> tree.root.left = Node(5, parent=tree.root) + >>> tree.root.right = Node(15, parent=tree.root) + >>> print("Before search:", tree.root.key) + >>> found = tree.search(5) + >>> print("Found:", found) + >>> print("After splay, new root:", tree.root.key) + """ + + tree = SplayTree() + tree.root = Node(10) + tree.root.left = Node(5, parent=tree.root) + tree.root.right = Node(15, parent=tree.root) + + print("Before search:", tree.root.key) + found = tree.search(5) + print("Found:", found) + print("After splay, new root:", tree.root.key)