详讲红黑树

目录

一、红黑树是什么?

二,红黑树代码实现

python:

c++

java:

perl

记得关注哦


一、红黑树是什么?

红黑树是一种自平衡的二叉搜索树,其特点是每个节点都带有颜色属性,可以是红色或黑色。红黑树满足以下性质:

  1. 每个节点是红色或黑色。
  2. 根节点是黑色。
  3. 每个叶节点(NIL节点,空节点)是黑色。
  4. 如果一个节点是红色,那么它的两个子节点都是黑色的。
  5. 对于每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑色节点。

这些性质保证了红黑树的平衡性,从而使得其在插入、删除和查找等操作的时间复杂度都能保持在较低的水平。红黑树广泛应用于各种数据结构和算法中,例如C++的STL库中的map和set,Java的TreeMap和TreeSet等。

 

二,红黑树代码实现

python:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
        self.color = "RED"


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

    def insert(self, data):
        node = Node(data)
        if self.root is None:
            node.color = "BLACK"
            self.root = node
        else:
            self._insert_helper(self.root, node)

    def _insert_helper(self, parent, node):
        if parent.data > node.data:
            if parent.left is None:
                parent.left = node
                node.parent = parent
            else:
                self._insert_helper(parent.left, node)
        else:
            if parent.right is None:
                parent.right = node
                node.parent = parent
            else:
                self._insert_helper(parent.right, node)

        self._fix_violation(node)

    def _fix_violation(self, node):
        while node.parent is not None and node.parent.color == "RED":
            if node.parent == node.parent.parent.left:
                uncle = node.parent.parent.right
                if uncle is not None and uncle.color == "RED":
                    node.parent.color = "BLACK"
                    uncle.color = "BLACK"
                    node.parent.parent.color = "RED"
                    node = node.parent.parent
                else:
                    if node == node.parent.right:
                        node = node.parent
                        self._left_rotate(node)
                    node.parent.color = "BLACK"
                    node.parent.parent.color = "RED"
                    self._right_rotate(node.parent.parent)
            else:
                uncle = node.parent.parent.left
                if uncle is not None and uncle.color == "RED":
                    node.parent.color = "BLACK"
                    uncle.color = "BLACK"
                    node.parent.parent.color = "RED"
                    node = node.parent.parent
                else:
                    if node == node.parent.left:
                        node = node.parent
                        self._right_rotate(node)
                    node.parent.color = "BLACK"
                    node.parent.parent.color = "RED"
                    self._left_rotate(node.parent.parent)

        self.root.color = "BLACK"

    def _left_rotate(self, node):
        temp = node.right
        node.right = temp.left
        if temp.left is not None:
            temp.left.parent = node
        temp.parent = node.parent
        if node.parent is None:
            self.root = temp
        elif node == node.parent.left:
            node.parent.left = temp
        else:
            node.parent.right = temp
        temp.left = node
        node.parent = temp

    def _right_rotate(self, node):
        temp = node.left
        node.left = temp.right
        if temp.right is not None:
            temp.right.parent = node
        temp.parent = node.parent
        if node.parent is None:
            self.root = temp
        elif node == node.parent.right:
            node.parent.right = temp
        else:
            node.parent.left = temp
        temp.right = node
        node.parent = temp

    def search(self, data):
        return self._search_helper(self.root, data)

    def _search_helper(self, node, data):
        if node is None or node.data == data:
            return node
        if node.data < data:
            return self._search_helper(node.right, data)
        return self._search_helper(node.left, data)

c++

#include <iostream>

// 定义红黑树节点的结构
struct Node {
    int data;
    Node* parent;
    Node* left;
    Node* right;
    bool isRed;
};

// 红黑树类定义
class RedBlackTree {
private:
    Node* root;
    
    // 对红黑树的插入操作
    void insertNode(int data) {
        Node* newNode = new Node;
        newNode->data = data;
        newNode->left = nullptr;
        newNode->right = nullptr;
        newNode->isRed = true;

        // 若树为空,则新节点直接作为根节点
        if (root == nullptr) {
            newNode->parent = nullptr;
            root = newNode;
        } else {
            Node* current = root;
            Node* parent = nullptr;

            while (current != nullptr) {
                parent = current;

                if (data < current->data) {
                    current = current->left;
                } else {
                    current = current->right;
                }
            }

            newNode->parent = parent;

            if (data < parent->data) {
                parent->left = newNode;
            } else {
                parent->right = newNode;
            }

            fixInsert(newNode);
        }
    }

    // 对红黑树的插入后修复操作
    void fixInsert(Node* newNode) {
        while (newNode->parent != nullptr && newNode->parent->isRed) {
            Node* parent = newNode->parent;
            Node* grandparent = parent->parent;

            // 父节点是祖父节点的左子节点
            if (parent == grandparent->left) {
                Node* uncle = grandparent->right;

                // Case 1: 叔叔节点也是红色
                if (uncle != nullptr && uncle->isRed) {
                    uncle->isRed = false;
                    parent->isRed = false;
                    grandparent->isRed = true;
                    newNode = grandparent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是右子节点
                    if (newNode == parent->right) {
                        rotateLeft(parent);
                        newNode = parent;
                        parent = newNode->parent;
                    }

                    // Case 3: 叔叔节点是黑色,且当前节点是左子节点
                    parent->isRed = false;
                    grandparent->isRed = true;
                    rotateRight(grandparent);
                }
            } else { // 父节点是祖父节点的右子节点
                Node* uncle = grandparent->left;

                // Case 1: 叔叔节点也是红色
                if (uncle != nullptr && uncle->isRed) {
                    uncle->isRed = false;
                    parent->isRed = false;
                    grandparent->isRed = true;
                    newNode = grandparent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是左子节点
                    if (newNode == parent->left) {
                        rotateRight(parent);
                        newNode = parent;
                        parent = newNode->parent;
                    }

                    // Case 3: 叔叔节点是黑色,且当前节点是右子节点
                    parent->isRed = false;
                    grandparent->isRed = true;
                    rotateLeft(grandparent);
                }
            }
        }

        root->isRed = false;
    }

    // 左旋操作
    void rotateLeft(Node* node) {
        Node* rightChild = node->right;
        node->right = rightChild->left;

        if (rightChild->left != nullptr) {
            rightChild->left->parent = node;
        }

        rightChild->parent = node->parent;

        if (node->parent == nullptr) {
            root = rightChild;
        } else if (node == node->parent->left) {
            node->parent->left = rightChild;
        } else {
            node->parent->right = rightChild;
        }

        rightChild->left = node;
        node->parent = rightChild;
    }

    // 右旋操作
    void rotateRight(Node* node) {
        Node* leftChild = node->left;
        node->left = leftChild->right;

        if (leftChild->right != nullptr) {
            leftChild->right->parent = node;
        }

        leftChild->parent = node->parent;

        if (node->parent == nullptr) {
            root = leftChild;
        } else if (node == node->parent->right) {
            node->parent->right = leftChild;
        } else {
            node->parent->left = leftChild;
        }

        leftChild->right = node;
        node->parent = leftChild;
    }

public:
    // 构造函数,初始化根节点为空
    RedBlackTree() {
        root = nullptr;
    }

    // 对外提供的插入节点接口
    void insert(int data) {
        insertNode(data);
    }
};

int main() {
    RedBlackTree rbTree;
    
    rbTree.insert(10);
    rbTree.insert(5);
    rbTree.insert(20);
    rbTree.insert(3);
    rbTree.insert(7);
    rbTree.insert(15);
    rbTree.insert(25);
    
    return 0;
}
 

java:

class Node {
    int data;
    Node parent;
    Node left;
    Node right;
    int color;
}

public class RedBlackTree {
    private Node root;
    private Node TNULL;

    // 前序遍历红黑树
    private void preOrderHelper(Node node) {
        if (node != TNULL) {
            System.out.print(node.data + " ");
            preOrderHelper(node.left);
            preOrderHelper(node.right);
        }
    }

    // 中序遍历红黑树
    private void inOrderHelper(Node node) {
        if (node != TNULL) {
            inOrderHelper(node.left);
            System.out.print(node.data + " ");
            inOrderHelper(node.right);
        }
    }

    // 后序遍历红黑树
    private void postOrderHelper(Node node) {
        if (node != TNULL) {
            postOrderHelper(node.left);
            postOrderHelper(node.right);
            System.out.print(node.data + " ");
        }
    }

    // 搜索树中值为key的节点
    private Node searchTreeHelper(Node node, int key) {
        if (node == TNULL || key == node.data) {
            return node;
        }

        if (key < node.data) {
            return searchTreeHelper(node.left, key);
        }
        return searchTreeHelper(node.right, key);
    }

    // 调整红黑树的颜色和结构,使其满足红黑树的特性
    private void fixInsert(Node k) {
        Node u;
        while (k.parent.color == 1) {
            if (k.parent == k.parent.parent.right) {
                u = k.parent.parent.left;
                if (u.color == 1) {
                    u.color = 0;
                    k.parent.color = 0;
                    k.parent.parent.color = 1;
                    k = k.parent.parent;
                } else {
                    if (k == k.parent.left) {
                        k = k.parent;
                        rightRotate(k);
                    }
                    k.parent.color = 0;
                    k.parent.parent.color = 1;
                    leftRotate(k.parent.parent);
                }
            } else {
                u = k.parent.parent.right;
                if (u.color == 1) {
                    u.color = 0;
                    k.parent.color = 0;
                    k.parent.parent.color = 1;
                    k = k.parent.parent;
                } else {
                    if (k == k.parent.right) {
                        k = k.parent;
                        leftRotate(k);
                    }
                    k.parent.color = 0;
                    k.parent.parent.color = 1;
                    rightRotate(k.parent.parent);
                }
            }
            if (k == root) {
                break;
            }
        }
        root.color = 0;
    }

    private void printHelper(Node root, String indent, boolean last) {
        if (root != TNULL) {
            System.out.print(indent);
            if (last) {
                System.out.print("R----");
                indent += "     ";
            } else {
                System.out.print("L----");
                indent += "|    ";
            }

            String sColor = root.color == 1 ? "RED" : "BLACK";
            System.out.println(root.data + "(" + sColor + ")");
            printHelper(root.left, indent, false);
            printHelper(root.right, indent, true);
        }
    }

    public RedBlackTree() {
        TNULL = new Node();
        TNULL.color = 0;
        TNULL.left = null;
        TNULL.right = null;
        root = TNULL;
    }

    // 前序遍历
    public void preorder() {
        preOrderHelper(this.root);
    }

    // 中序遍历
    public void inorder() {
        inOrderHelper(this.root);
    }

    // 后序遍历
    public void postorder() {
        postOrderHelper(this.root);
    }

    // 查找树中值为key的节点
    public Node searchTree(int k) {
        return searchTreeHelper(this.root, k);
    }

    // 获取树中最小值节点
    public Node minimum(Node node) {
        while (node.left != TNULL) {
            node = node.left;
        }
        return node;
    }

    // 获取树中最大值节点
    public Node maximum(Node node) {
        while (node.right != TNULL) {
            node = node.right;
        }
        return node;
    }

    // 左旋转
    private void leftRotate(Node x) {
        Node y = x.right;
        x.right = y.left;
        if (y.left != TNULL) {
            y.left.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            this.root = y;
        } else if (x == x.parent.left) {
            x.parent.left = y;
        } else {
            x.parent.right = y;
        }
        y.left = x;
        x.parent = y;
    }

    // 右旋转
    private void rightRotate(Node x) {
        Node y = x.left;
        x.left = y.right;
        if (y.right != TNULL) {
            y.right.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            this.root = y;
        } else if (x == x.parent.right) {
            x.parent.right = y;
        } else {
            x.parent.left = y;
        }
        y.right = x;
        x.parent = y;
    }

    // 插入节点到红黑树
    public void insert(int key) {
        Node node = new Node();
        node.parent = null;
        node.data = key;
        node.left = TNULL;
        node.right = TNULL;
        node.color = 1;

        Node y = null;
        Node x = this.root;

        while (x != TNULL) {
            y = x;
            if (node.data < x.data) {
                x = x.left;
            } else {
                x = x.right;
            }
        }

        node.parent = y;
        if (y == null) {
            root = node;
        } else if (node.data < y.data) {
            y.left = node;
        } else {
            y.right = node;
        }

        if (node.parent == null) {
            node.color = 0;
            return;
        }

        if (node.parent.parent == null) {
            return;
        }

        fixInsert(node);
    }

    // 删除红黑树中的节点
    private void fixDelete(Node x) {
        Node s;
        while (x != root && x.color == 0) {
            if (x == x.parent.left) {
                s = x.parent.right;
                if (s.color == 1) {
                    s.color = 0;
                    x.parent.color = 1;
                    leftRotate(x.parent);
                    s = x.parent.right;
                }

                if (s.left.color == 0 && s.right.color == 0) {
                    s.color = 1;
                    x = x.parent;
                } else {
                    if (s.right.color == 0) {
                        s.left.color = 0;
                        s.color = 1;
                        rightRotate(s);
                        s = x.parent.right;
                    }
                    s.color = x.parent.color;
                    x.parent.color = 0;
                    s.right.color = 0;
                    leftRotate(x.parent);
                    x = root;
                }
            } else {
                s = x.parent.left;
                if (s.color == 1) {
                    s.color = 0;
                    x.parent.color = 1;
                    rightRotate(x.parent);
                    s = x.parent.left;
                }

                if (s.right.color == 0 && s.right.color == 0) {
                    s.color = 1;
                    x = x.parent;
                } else {
                    if (s.right.color == 0) {
                        s.right.color = 0;
                        s.color = 1;
                        leftRotate(s);
                        s = x.parent.left;
                    }
                    s.color = x.parent.color;
                    x.parent.color = 0;
                    s.left.color = 0;
                    rightRotate(x.parent);
                    x = root;
                }
            }
        }
        x.color = 0;
    }

    // 删除节点
    private void rbTransplant(Node u, Node v) {
        if (u.parent == null) {
            root = v;
        } else if (u == u.parent.left) {
            u.parent.left = v;
        } else {
            u.parent.right = v;
        }
        v.parent = u.parent;
    }

    // 删除红黑树中的节点
    private void deleteNodeHelper(Node node, int key) {
        Node z = TNULL 

perl

#!/usr/bin/perl

package RedBlackTree;

use strict;
use warnings;

# 定义红黑树节点
package Node;

use strict;
use warnings;

sub new {
    my ($class, $key, $value) = @_;
    my $self = {
        left   => undef,  # 左子节点
        right  => undef,  # 右子节点
        parent => undef,  # 父节点
        key    => $key,   # 键值
        value  => $value, # 值
        color  => 'RED'   # 颜色
    };
    bless $self, $class;
    return $self;
}

# 红黑树
package RedBlackTree;

use strict;
use warnings;

sub new {
    my ($class) = @_;
    my $self = {
        root => undef # 根节点
    };
    bless $self, $class;
    return $self;
}

# 左旋操作
sub rotate_left {
    my ($self, $node) = @_;

    my $right_child = $node->{right};  # 右子节点
    $node->{right} = $right_child->{left};

    if ($right_child->{left}) {
        $right_child->{left}->{parent} = $node;
    }

    $right_child->{parent} = $node->{parent};

    if (!$node->{parent}) {
        $self->{root} = $right_child;
    } elsif ($node == $node->{parent}->{left}) {
        $node->{parent}->{left} = $right_child;
    } else {
        $node->{parent}->{right} = $right_child;
    }

    $right_child->{left} = $node;
    $node->{parent} = $right_child;
}

# 右旋操作
sub rotate_right {
    my ($self, $node) = @_;

    my $left_child = $node->{left};   # 左子节点
    $node->{left} = $left_child->{right};

    if ($left_child->{right}) {
        $left_child->{right}->{parent} = $node;
    }

    $left_child->{parent} = $node->{parent};

    if (!$node->{parent}) {
        $self->{root} = $left_child;
    } elsif ($node == $node->{parent}->{right}) {
        $node->{parent}->{right} = $left_child;
    } else {
        $node->{parent}->{left} = $left_child;
    }

    $left_child->{right} = $node;
    $node->{parent} = $left_child;
}

# 插入节点
sub insert {
    my ($self, $key, $value) = @_;

    my $new_node = Node->new($key, $value);
    my $current = $self->{root};
    my $parent = undef;

    while ($current) {
        $parent = $current;

        if ($key < $current->{key}) {
            $current = $current->{left};
        } else {
            $current = $current->{right};
        }
    }

    $new_node->{parent} = $parent;

    if (!$parent) {
        $self->{root} = $new_node;
    } elsif ($key < $parent->{key}) {
        $parent->{left} = $new_node;
    } else {
        $parent->{right} = $new_node;
    }

    $self->insert_fixup($new_node);
}

# 插入后修复红黑树
sub insert_fixup {
    my ($self, $node) = @_;

    while ($node->{parent} && $node->{parent}->{color} eq 'RED') {
        if ($node->{parent} == $node->{parent}->{parent}->{left}) {
            my $uncle = $node->{parent}->{parent}->{right};

            if ($uncle && $uncle->{color} eq 'RED') {
                $node->{parent}->{color} = 'BLACK';
                $uncle->{color} = 'BLACK';
                $node->{parent}->{parent}->{color} = 'RED';
                $node = $node->{parent}->{parent};
            } else {
                if ($node == $node->{parent}->{right}) {
                    $node = $node->{parent};
                    $self->rotate_left($node);
                }

                $node->{parent}->{color} = 'BLACK';
                $node->{parent}->{parent}->{color} = 'RED';
                $self->rotate_right($node->{parent}->{parent});
            }
        } else {
            my $uncle = $node->{parent}->{parent}->{left};

            if ($uncle && $uncle->{color} eq 'RED') {
                $node->{parent}->{color} = 'BLACK';
                $uncle->{color} = 'BLACK';
                $node->{parent}->{parent}->{color} = 'RED';
                $node = $node->{parent}->{parent};
            } else {
                if ($node == $node->{parent}->{left}) {
                    $node = $node->{parent};
                    $self->rotate_right($node);
                }

                $node->{parent}->{color} = 'BLACK';
                $node->{parent}->{parent}->{color} = 'RED';
                $self->rotate_left($node->{parent}->{parent});
            }
        }
    }

    $self->{root}->{color} = 'BLACK';
}

# 执行示例
package main;

use strict;
use warnings;

my $rbt = RedBlackTree->new();

$rbt->insert(10, 'A');
$rbt->insert(20, 'B');
$rbt->insert(30, 'C');
$rbt->insert(40, 'D');
$rbt->insert(50, 'E');

print "根节点: ", $rbt->{root}->{value}, "\n";

print "左子节点: ", $rbt->{root}->{left}->{value}, "\n";
print "右子节点: ", $rbt->{root}->{right}->{value}, "\n";

print "左子节点的父节点: ", $rbt->{root}->{left}->{parent}->{value}, "\n";
print "右子节点的父节点: ", $rbt->{root}->{right}->{parent}->{value}, "\n";
 

记得关注哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值