红黑树的rotation是什么
时间: 2023-12-04 10:38:05 浏览: 116
红黑树的rotation是指通过旋转节点来保持红黑树的平衡。旋转操作有两种:左旋和右旋。左旋是指将一个节点的右子节点旋转到该节点的位置,同时该节点成为其右子节点的左子节点。右旋是指将一个节点的左子节点旋转到该节点的位置,同时该节点成为其左子节点的右子节点。旋转操作可以保持红黑树的性质不变,同时也可以使得红黑树的结构更加平衡。
相关问题
红黑树和树的区别,啥时候变成红黑树
红黑树是一种自平衡的二叉查找树,它在保持二叉搜索树特性的同时,通过额外的颜色标记(红色和黑色),保证了在最坏情况下的操作性能。红黑树的主要区别于普通二叉树在于其结构约束:
1. 每个节点要么是红色,要么是黑色。
2. 根节点是黑色。
3. 所有叶子节点(空节点)都是黑色。
4. 如果一个节点是红色,那么它的两个子节点必须是黑色。
5. 从任一节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
当插入或删除操作导致红黑树的性质不再满足时,就需要进行调整,这个过程称为“重新着色”(re-coloring)或“旋转”(rotation)。比如,在插入新节点后可能导致某个路径上有过多的红色节点,这时需要通过变色和旋转操作将其恢复到红黑树的状态,以维持其性能保证。
生成一个红黑树代码C++
### 回答1:
这是一段简单的红黑树代码C:#include<stdio.h>
struct node
{
int key;
struct node *left, *right;
int color;
};
// A Red-Black tree node structure
struct node *newNode(int key)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = key;
temp->left = temp->right = NULL;
temp->color = 1; // 1 for red, 0 for black
return temp;
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node *rightRotate(struct node *y)
{
struct node *x = y->left;
struct node *T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
struct node *T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Return new root
return y;
}
// This function fixes the Red-Black tree
void fixViolation(struct node *temp)
{
struct node *parent_temp = NULL;
struct node *grand_parent_temp = NULL;
while ((temp != root) && (temp->color != 0) &&
(temp->parent->color == 1))
{
parent_temp = temp->parent;
grand_parent_temp = temp->parent->parent;
/* Case : A
Parent of temp is left child of Grand-parent of temp */
if (parent_temp == grand_parent_temp->left)
{
struct node *uncle_temp = grand_parent_temp->right;
/* Case : 1
The uncle of temp is also red
Only Recoloring required */
if (uncle_temp != NULL && uncle_temp->color == 1)
{
grand_parent_temp->color = 1;
parent_temp->color = 0;
uncle_temp->color = 0;
temp = grand_parent_temp;
}
else
{
/* Case : 2
temp is right child of its parent
Left-rotation required */
if (temp == parent_temp->right)
{
temp = parent_temp;
leftRotate(temp);
}
/* Case : 3
temp is left child of its parent
Right-rotation required */
rightRotate(grand_parent_temp);
swap(parent_temp->color,
grand_parent_temp->color);
temp = parent_temp;
}
}
/* Case : B
Parent of temp is right child of Grand-parent of temp */
else
{
struct node *uncle_temp = grand_parent_temp->left;
/* Case : 1
The uncle of temp is also red
Only Recoloring required */
if ((uncle_temp != NULL) && (uncle_temp->color == 1))
{
grand_parent_temp->color = 1;
parent_temp->color = 0;
uncle_temp->color = 0;
temp = grand_parent_temp;
}
else
{
/* Case : 2
temp is left child of its parent
Right-rotation required */
if (temp == parent_temp->left)
{
temp = parent_temp;
rightRotate(temp);
}
/* Case : 3
temp is right child of its parent
Left-rotation required */
leftRotate(grand_parent_temp);
swap(parent_temp->color,
grand_parent_temp->color);
temp = parent_temp;
}
}
}
root->color = 0;
}
### 回答2:
红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它的每个节点都具有一个颜色属性,可以是红色或黑色。红黑树具有以下几个性质:
1. 每个节点要么是红色,要么是黑色。
2. 根节点是黑色。
3. 叶子节点(NIL节点,空节点)是黑色。
4. 如果一个节点是红色,则它的两个子节点都是黑色(不能出现连续的红色节点)。
5. 对于每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑色节点。
以下是一个简单实现红黑树的C代码:
```c
#include <stdio.h>
#include <stdlib.h>
enum Color {RED, BLACK};
// 红黑树节点结构定义
typedef struct node {
int data;
enum Color color;
struct node *left, *right, *parent;
} Node;
// 红黑树结构定义
typedef struct rbtree {
Node *root;
Node *nil;
} RBTree;
// 左旋操作
void leftRotate(RBTree *tree, Node *x) {
Node *y = x->right;
x->right = y->left;
if (y->left != tree->nil) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == tree->nil) {
tree->root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
// 右旋操作
void rightRotate(RBTree *tree, Node *y) {
Node *x = y->left;
y->left = x->right;
if (x->right != tree->nil) {
x->right->parent = y;
}
x->parent = y->parent;
if (y->parent == tree->nil) {
tree->root = x;
} else if (y == y->parent->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
x->right = y;
y->parent = x;
}
// 插入操作的修复
void insertFixup(RBTree *tree, Node *z) {
while (z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node *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;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(tree, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(tree, z->parent->parent);
}
} else {
Node *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;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(tree, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(tree, z->parent->parent);
}
}
}
tree->root->color = BLACK;
}
// 插入操作
void insert(RBTree *tree, int data) {
Node *z = (Node *) malloc(sizeof(Node));
z->data = data;
z->color = RED;
z->left = tree->nil;
z->right = tree->nil;
Node *y = tree->nil;
Node *x = tree->root;
while (x != tree->nil) {
y = x;
if (z->data < x->data) {
x = x->left;
} else {
x = x->right;
}
}
z->parent = y;
if (y == tree->nil) {
tree->root = z;
} else if (z->data < y->data) {
y->left = z;
} else {
y->right = z;
}
insertFixup(tree, z);
}
// 中序遍历
void inorderTraversal(RBTree *tree, Node *root) {
if (root != tree->nil) {
inorderTraversal(tree, root->left);
printf("%d ", root->data);
inorderTraversal(tree, root->right);
}
}
int main() {
RBTree tree;
Node nilNode;
tree.nil = &nilNode;
tree.nil->color = BLACK;
tree.root = tree.nil;
// 插入节点
insert(&tree, 5);
insert(&tree, 2);
insert(&tree, 7);
insert(&tree, 1);
insert(&tree, 3);
insert(&tree, 6);
insert(&tree, 8);
// 中序遍历输出
inorderTraversal(&tree, tree.root);
printf("\n");
return 0;
}
```
以上代码实现了红黑树的插入操作,并通过中序遍历的方式输出了插入后的红黑树节点数据。可以根据需要修改插入数据和遍历方式来进行测试。
### 回答3:
红黑树是一种自平衡的二叉搜索树,其在插入和删除操作后通过一系列旋转和重新着色操作来保持平衡。
下面是一个简单的红黑树的 C 代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义红黑树的节点结构
typedef struct Node {
int data; // 节点存储的数据
enum { RED, BLACK } color; // 节点的颜色
struct Node *parent; // 指向父节点的指针
struct Node *left; // 指向左子节点的指针
struct Node *right; // 指向右子节点的指针
} Node;
// 全局变量,表示红黑树的根节点
Node *root = NULL;
// 左旋操作
void leftRotate(Node *x) {
Node *y = x->right;
x->right = y->left;
if (y->left != NULL) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL) {
root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
// 右旋操作
void rightRotate(Node *x) {
Node *y = x->left;
x->left = y->right;
if (y->right != NULL) {
y->right->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL) {
root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->right = x;
x->parent = y;
}
// 插入操作
void insert(int data) {
Node *node = (Node *)malloc(sizeof(Node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->color = RED;
Node *y = NULL;
Node *x = root;
while (x != NULL) {
y = x;
if (data < x->data) {
x = x->left;
} else {
x = x->right;
}
}
node->parent = y;
if (y == NULL) {
root = node;
} else if (data < y->data) {
y->left = node;
} else {
y->right = node;
}
insertFixup(node);
}
// 插入修正操作
void insertFixup(Node *z) {
while (z->parent != NULL && z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node *y = z->parent->parent->right;
if (y != NULL && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(z->parent->parent);
}
} else {
Node *y = z->parent->parent->left;
if (y != NULL && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
// 中序遍历输出红黑树
void inorderTraversal(Node *node) {
if (node != NULL) {
inorderTraversal(node->left);
printf("%d\n", node->data);
inorderTraversal(node->right);
}
}
int main() {
insert(5);
insert(3);
insert(8);
insert(1);
insert(4);
insert(6);
insert(9);
printf("红黑树中序遍历结果:\n");
inorderTraversal(root);
return 0;
}
```
该代码实现了红黑树的基本操作,包括左旋、右旋、插入和插入修正等。每个节点包含数据、颜色和指向父节点、左子节点和右子节点的指针。插入操作使用了插入修正来保持红黑树的平衡性。
通过在 `main` 函数中插入一些数据,即可得到生成的红黑树,并通过中序遍历输出树中节点的数据,以验证树结构是否正确。
阅读全文