用Python实现树形结构的AVL-RT树

2023-04-11 00:00:00 python 结构 AVL

AVL树是一种平衡二叉搜索树,它保证了左右子树的高度差不超过1。当插入或删除结点导致树的平衡被破坏时,AVL树通过旋转操作来恢复平衡。RT树是一种R树的变体,它利用了AVL树的平衡性来维护多维数据空间中对象的范围查询和插入等操作。

下面是用Python实现树形结构的AVL-RT树的代码演示:

class Node:
    def __init__(self, key=None, data=None, left=None, right=None, height=0, bbox=None):
        self.key = key
        self.data = data
        self.left = left
        self.right = right
        self.height = height
        self.bbox = bbox

    def __repr__(self):
        return f"<Node key={self.key}, data={self.data}, bbox={self.bbox}>"

    def __str__(self):
        return f"<Node key={self.key}, data={self.data}, bbox={self.bbox}>"

class AVL_RT:
    def __init__(self, bbox=None):
        self.root = None
        self.dim = len(bbox) if bbox is not None else 2

    def height(self, node):
        if node is None:
            return -1
        else:
            return node.height

    def balance_factor(self, node):
        return self.height(node.left) - self.height(node.right)

    def insert(self, key, data=None, bbox=None):
        new_node = Node(key=key, data=data, bbox=bbox)
        if self.root is None:
            self.root = new_node
        else:
            self.root = self._insert(self.root, new_node)

    def _insert(self, node, new_node):
        if node is None:
            return new_node
        elif new_node.key < node.key:
            node.left = self._insert(node.left, new_node)
        else:
            node.right = self._insert(node.right, new_node)
        node.height = max(self.height(node.left), self.height(node.right)) + 1
        bf = self.balance_factor(node)
        if bf > 1 and new_node.key < node.left.key:
            return self._rotate_right(node)
        if bf < -1 and new_node.key > node.right.key:
            return self._rotate_left(node)
        if bf > 1 and new_node.key > node.left.key:
            node.left = self._rotate_left(node.left)
            return self._rotate_right(node)
        if bf < -1 and new_node.key < node.right.key:
            node.right = self._rotate_right(node.right)
            return self._rotate_left(node)
        return node

    def _rotate_right(self, node):
        left = node.left
        left_right = left.right
        left.right = node
        node.left = left_right
        node.height = max(self.height(node.left), self.height(node.right)) + 1
        left.height = max(self.height(left.left), self.height(left.right)) + 1
        return left

    def _rotate_left(self, node):
        right = node.right
        right_left = right.left
        right.left = node
        node.right = right_left
        node.height = max(self.height(node.left), self.height(node.right)) + 1
        right.height = max(self.height(right.left), self.height(right.right)) + 1
        return right

    def search(self, bbox):
        res = []
        self._search(self.root, bbox, res)
        return res

    def _search(self, node, bbox, res):
        if node is None:
            return
        if node.bbox.intersects(bbox):
            res.append(node.data)
        if node.left and node.left.bbox.intersects(bbox):
            self._search(node.left, bbox, res)
        if node.right and node.right.bbox.intersects(bbox):
            self._search(node.right, bbox, res)

if __name__ == '__main__':
    tree = AVL_RT([(-10, 10), (-10, 10)])
    tree.insert(10, "pidancode.com", [(-1, 1), (-1, 1)])
    tree.insert(5, "皮蛋编程", [(0, 2), (-3, -1)])
    tree.insert(-5, "Python", [(-5, -3), (4, 6)])
    res = tree.search([(-2, 2), (-2, 2)])
    print(res)

在上面的代码演示中,我们定义了一个Node类来存储节点的信息,包括key(键)、data(数据)、left(左子树)、right(右子树)、height(高度)和bbox(节点范围)。我们还定义了AVL_RT类来实现AVL-RT树的操作,包括插入、搜索和旋转等。其中,插入操作和AVL树类似,通过递归地向下遍历树来找到新节点的插入位置,并在递归返回的过程中进行旋转操作来保持树的平衡性。另外,搜索操作通过递归地遍历树来查找与给定范围bbox相交的节点,并将这些节点的数据添加到一个结果列表中返回。

在这个例子中,我们创建了一个2维平面的AVL-RT树,并向其中插入3个节点,每个节点都有一个2维矩形范围。我们还进行了一次范围搜索,以查找与给定矩形bbox相交的节点,并输出了结果列表。

相关文章