[python] 红黑树

    最近学习数据结构,对红黑树了解了一番。红黑树单独来看比较晦涩,插入和删除过程难以理解,记忆难度大,但是通过和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()


猜你喜欢

转载自blog.csdn.net/b2011212205/article/details/80392297