📜  红黑树vs AVL树(1)

📅  最后修改于: 2023-12-03 15:27:32.434000             🧑  作者: Mango

红黑树 vs AVL树

介绍

红黑树和AVL树是两种非常常见的自平衡搜索树,在实际开发中都有广泛的应用。自平衡搜索树是一种特殊的二叉搜索树,能够自动进行插入、删除等操作时进行自动平衡,以保证树的深度相对较小,从而能够快速地进行查找操作。

区别

虽然红黑树和AVL树都是自平衡搜索树,但是它们在实现上有很大的区别。

AVL树

AVL树是一种高度平衡的二叉搜索树,即每个节点的左子树和右子树的深度高度差不能超过1。在插入或删除节点时,如果出现失衡,就通过单旋转或双旋转进行调整,使树重新平衡。因此,AVL树保证了每个节点的平衡性,但可能会导致频繁的旋转操作,影响了插入和删除操作的效率。

红黑树

红黑树也是一种自平衡搜索树,但在实现上比AVL树“宽松”一些,不要求树的每个节点都是高度平衡的,而是限制了红黑树的五个性质:

  • 每个节点要么是红色,要么是黑色;
  • 根节点是黑色的;
  • 每个叶节点(NIL节点,即空节点)是黑色的;
  • 如果一个节点是红色的,则它的子节点必须是黑色的;
  • 从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。

这些性质确保了红黑树相对AVL树更加宽松,减少了旋转操作的次数,提高了插入和删除操作的效率,同时仍能保证树的深度相对较小。

总结

AVL树和红黑树都是常见的自平衡搜索树,并且各有优缺点。AVL树保证了树的高度平衡,但可能会导致频繁的旋转操作,影响了插入和删除操作的效率;而红黑树更加宽松,减少了旋转操作的次数,提高了插入和删除操作的效率,同时能够保证树的深度相对较小。在实际开发中,应根据具体情况选择使用哪种自平衡搜索树。

代码片段

下面是一个简单的Python实现红黑树:

class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
        self.color = 'R'

class RedBlackTree:
    def __init__(self):
        self.root = None

    def __in_order(self, node):
        if node is not None:
            self.__in_order(node.left)
            print(node.key, end=" ")
            self.__in_order(node.right)

    def in_order(self):
        self.__in_order(self.root)

    def insert(self, key):
        node = Node(key)
        node.left = None
        node.right = None
        node.color = 'R'
        if self.root is None:
            self.root = node
            node.color = 'B'
            return
        curr = self.root
        parent = None
        while True:
            if curr.key == key:
                return
            parent = curr
            if key < curr.key:
                curr = curr.left
                if curr is None:
                    parent.left = node
                    break
            else:
                curr = curr.right
                if curr is None:
                    parent.right = node
                    break
        if parent.color == 'R' and node.color == 'R':
            self.__re_balance(parent, node)

    def __rotate_left(self, node):
        r = node.right
        node.right = r.left
        if r.left is not None:
            r.left.parent = node
        r.parent = node.parent
        if node.parent is None:
            self.root = r
        else:
            if node == node.parent.left:
                node.parent.left = r
            else:
                node.parent.right = r
        r.left = node
        node.parent = r

    def __rotate_right(self, node):
        l = node.left
        node.left = l.right
        if l.right is not None:
            l.right.parent = node
        l.parent = node.parent
        if node.parent is None:
            self.root = l
        else:
            if node == node.parent.right:
                node.parent.right = l
            else:
                node.parent.left = l
        l.right = node
        node.parent = l

    def __re_balance(self, x, y):
        while y.color == 'R':
            if y == x.right:
                if x.left and x.left.color == 'R':
                    x.left.color = 'B'
                    x.color = 'R'
                    self.__rotate_right(x)
                else:
                    if y == x.right.left:
                        self.__rotate_right(y.parent)
                        y = y.right
                    x.color, y.color = y.color, x.color
                    self.__rotate_left(x)
            else:
                if x.right and x.right.color == 'R':
                    x.right.color = 'B'
                    x.color = 'R'
                    self.__rotate_left(x)
                else:
                    if y == x.left.right:
                        self.__rotate_left(y.parent)
                        y = y.left
                    x.color, y.color = y.color, x.color
                    self.__rotate_right(x)
        self.root.color = 'B'

参考资料:https://en.wikipedia.org/wiki/Red%E2%80%93black_tree