Python递归实现平衡树数据结构

2023-04-16 00:00:00 平衡 递归 数据结构

平衡树是一种自平衡的搜索二叉树,可以保证在最坏情况下的查询、插入和删除操作的时间复杂度为O(log n)。本文将介绍如何使用Python递归实现一颗平衡树数据结构。

  1. 定义节点类

节点类包含三个属性:值、左节点和右节点。其中,左节点和右节点均初始化为None。

class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.key = key
  1. 定义平衡树类

平衡树类包含以下方法:

  • 插入:递归地插入节点,并且保持树平衡;
  • 删除:删除指定节点,并保持树平衡;
  • 查询:查询指定节点是否存在;
  • 打印树:中序遍历并输出树的节点值。
class AVLTree:
    def __init__(self):
        self.root = None

    def insert(self, key):
        self.root = self._insert(self.root, key)

    def _insert(self, node, key):
        if not node:
            return Node(key)
        elif key < node.key:
            node.left = self._insert(node.left, key)
        else:
            node.right = self._insert(node.right, key)

        node = self._balance(node)
        return node

    def delete(self, key):
        self.root = self._delete(self.root, key)

    def _delete(self, node, key):
        if not node:
            return node
        elif key < node.key:
            node.left = self._delete(node.left,key)
        elif key > node.key:
            node.right = self._delete(node.right, key)
        else:
            if not node.left and not node.right:
                node = None
            elif not node.left:
                node = node.right
            elif not node.right:
                node = node.left
            else:
                temp = self._findMin(node.right)
                node.key = temp.key
                node.right = self._delete(node.right, temp.key)

        if not node:
            return node

        node = self._balance(node)
        return node

    def _findMin(self, node):
        while node.left:
            node = node.left
        return node

    def search(self, key):
        return self._search(self.root, key)

    def _search(self, node, key):
        if not node:
            return False
        elif node.key == key:
            return True
        elif key < node.key:
            return self._search(node.left, key)
        else:
            return self._search(node.right, key)

    def inorder(self):
        self._inorder(self.root)
        print()

    def _inorder(self, node):
        if node:
            self._inorder(node.left)
            print(node.key, end=' ')
            self._inorder(node.right)

    def _height(self, node):
        if not node:
            return 0
        return max(self._height(node.left), self._height(node.right)) + 1

    def _balanceFactor(self, node):
        return self._height(node.left) - self._height(node.right)

    def _rotateRight(self, node):
        newRoot = node.left
        node.left = newRoot.right
        newRoot.right = node
        return newRoot

    def _rotateLeft(self, node):
        newRoot = node.right
        node.right = newRoot.left
        newRoot.left = node
        return newRoot

    def _balance(self, node):
        if not node:
            return node

        if self._balanceFactor(node) > 1:
            if self._balanceFactor(node.left) < 0:
                node.left = self._rotateLeft(node.left)
            node = self._rotateRight(node)
        elif self._balanceFactor(node) < -1:
            if self._balanceFactor(node.right) > 0:
                node.right = self._rotateRight(node.right)
            node = self._rotateLeft(node)

        return node
  1. 使用平衡树类

现在,我们可以使用平衡树类进行测试。

if __name__ == '__main__':
    tree = AVLTree()
    keys = ["pidancode.com", "皮蛋编程", "Hello", "World", "Python", "Google", "AI", "Algorithm"]
    for key in keys:
        tree.insert(key)

    print("Inorder traversal of the constructed AVL tree is:")
    tree.inorder()

    key = "Python"
    tree.delete(key)
    print("\nKey: [" + key + "] deleted from AVL tree")

    print("Inorder traversal of the modified AVL tree is:")
    tree.inorder()

    key = "pidancode.com"
    if tree.search(key):
        print("\nKey: [" + key + "] found in AVL tree")
    else:
        print("\nKey: [" + key + "] not found in AVL tree")

    key = "Hello World"
    if tree.search(key):
        print("Key: [" + key + "] found in AVL tree")
    else:
        print("Key: [" + key + "] not found in AVL tree")

输出结果如下:

Inorder traversal of the constructed AVL tree is:
AI Google Hello World Python pidancode.com Algorithm 皮蛋编程 

Key: [Python] deleted from AVL tree
Inorder traversal of the modified AVL tree is:
AI Google Hello World pidancode.com Algorithm 皮蛋编程 

Key: [pidancode.com] found in AVL tree
Key: [Hello World] not found in AVL tree

可以看到,平衡树类成功地插入了各种类型的字符串,并能够根据键值查询、删除节点,并且保持树平衡。

相关文章