最近学习数据结构,对红黑树了解了一番。红黑树单独来看比较晦涩,插入和删除过程难以理解,记忆难度大,但是通过和2-3树的比较学习,很容易就能理解,建议学习红黑树的同志都去看看2-3树。
下面是用python实现的红黑树,只有插入部分,效果图如下:
代码如下:
# -*- coding: utf-8 -*- from graphviz import Digraph import random RED = 0 BLACK = 1 class NIL: def __init__(self): self.color = BLACK self.value = "NIL" NIL = NIL() class Node: def __init__(self, value): self.parent = NIL self.left = NIL self.right = NIL self.color = RED self.value = value class RBTree: def __init__(self, l): self.root = NIL for value in l: self.insert(value) def insert(self, value): y = NIL x = self.root z = Node(value) while x is not NIL: y = x if x.value < value: x = x.right else: x = x.left z.parent = y if y is NIL: self.root = z elif y.value < z.value: y.right = z else: y.left = z self.insert_fix(z) def insert_fix(self, z): while z.parent.color == RED: if z.parent is z.parent.parent.left: y = z.parent.parent.right if y.color == RED: z.parent.color = BLACK y.color = BLACK z.parent.parent.color = RED z = z.parent.parent elif z is z.parent.right: z = z.parent self.left_rotate(z) else: z.parent.color = BLACK z.parent.parent.color = RED self.right_rotate(z.parent.parent) else: y = z.parent.parent.left if y.color == RED: z.parent.color = BLACK y.color = BLACK z.parent.parent.color = RED z = z.parent.parent elif z is z.parent.left: z = z.parent self.right_rotate(z) else: z.parent.color = BLACK z.parent.parent.color = RED self.left_rotate(z.parent.parent) self.root.color = BLACK def left_rotate(self, x): y = x.right x.right = y.left if y.left is not NIL: y.left.parent = x y.parent = x.parent if x.parent is NIL: self.root = y elif x is x.parent.left: x.parent.left = y else: x.parent.right = y y.left = x x.parent = y def right_rotate(self, y): x = y.left y.left = x.right if x.right is not NIL: x.right.parent = y x.parent = y.parent if y.parent is NIL: self.root = x elif y is y.parent.left: y.parent.left = x else: y.parent.right = x x.right = y y.parent = y def show(self): def ergodic_node(dot, label_node, node): if node is not NIL: label_left = str(node.left).join(str(random.randint(0, 9999))).join(str(random.randint(0, 9999))) label_right = str(node.right).join(str(random.randint(0, 9999))).join(str(random.randint(0, 9999))) dot.node(label_node, str(node.value)) dot.node(label_left, str(node.left.value)) dot.node(label_right, str(node.right.value)) dot.edge(label_node, label_left) dot.edge(label_node, label_right) ergodic_node(dot, label_left, node.left) ergodic_node(dot, label_right, node.right) dot = Digraph(format="jpeg") label_node = str(self.root).join(str(random.randint(0, 9999))).join(str(random.randint(0, 9999))) ergodic_node(dot, label_node, self.root) dot.view() if __name__ == "__main__": a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] tree = RBTree(a) print(tree) tree.show()