目录
一、红黑树是什么?
红黑树是一种自平衡的二叉搜索树,其特点是每个节点都带有颜色属性,可以是红色或黑色。红黑树满足以下性质:
- 每个节点是红色或黑色。
- 根节点是黑色。
- 每个叶节点(NIL节点,空节点)是黑色。
- 如果一个节点是红色,那么它的两个子节点都是黑色的。
- 对于每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑色节点。
这些性质保证了红黑树的平衡性,从而使得其在插入、删除和查找等操作的时间复杂度都能保持在较低的水平。红黑树广泛应用于各种数据结构和算法中,例如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";