根据之前红黑树的原理和《算法导论》上面的伪代码,我用代码将增加和调整的代码实现了一下,如有不对请大家指正。代码可以结合前两篇文章看。
这次把剩下的删除结加上了,经过测试是可以使用的。
红黑树的详细介绍一
红黑树详细介绍二
/*
* =====================================================================================
*
* Filename: rbtree->h
*
* Description: red black tree
*
* Version: 1->0
* Created: 2014年05月05日 08时48分50秒
* Revision: none
* Compiler: gcc
*
* Author: 我叫程序猿XXX
* Company:
*
* =====================================================================================
*/
#ifndef __RBTREE__H
#define __RBTREE__H
#define bool int
#define successed 0
#define failed -1
#define BLACK 0
#define RED 1
typedef struct _rbtree_node{
struct _rbtree_node *p;
struct _rbtree_node *left;
struct _rbtree_node *right;
int key;
int color;
}*p_rbtree_node;
struct _rbtree_node node;
p_rbtree_node getNode(p_rbtree_node x);
bool leftRotate(p_rbtree_node *root, p_rbtree_node x);
bool rightRotate(p_rbtree_node *root, p_rbtree_node x);
bool rbInert(p_rbtree_node *root, p_rbtree_node z);
bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z);
bool rbBuilt(void);
bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v);
bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x);
p_rbtree_node Delete(p_rbtree_node z);
p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z);
p_rbtree_node treeMinimum(p_rbtree_node z);
p_rbtree_node Search(int key);
p_rbtree_node priSearch(p_rbtree_node *root, int key);
void rbDisplay(p_rbtree_node *root);
void Display(void);
#endif
rbtree.c
/*
* =====================================================================================
*
* Filename: rbtree.c
*
* Description:
*
* Version: 1.0
* Created: 2014年05月05日 09时01分00秒
* Revision: none
* Compiler: gcc
*
* Author: 我叫程序猿XXX
* Company:
*
* =====================================================================================
*/
#include "rbtree.h"
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
p_rbtree_node nil = &node;
p_rbtree_node root;
p_rbtree_node getNode(p_rbtree_node x)
{
x = NULL;
x = (p_rbtree_node)malloc(sizeof(struct _rbtree_node));
if (x == NULL)
{
return NULL;
}
memset(x, 0, sizeof(struct _rbtree_node));
return x;
}
bool leftRotate(p_rbtree_node *root, p_rbtree_node x)
{
p_rbtree_node y = NULL;
y = x->right; //set y
x->right = y->left;
if (y->left != nil)
y->left->p = x;
y->p = x->p;
if (x->p == nil)
*root = y;
else if (x == x->p->left)
x->p->left = y;
else
x->p->right = y;
y->left = x;
x->p = y;
return successed;
}
bool rightRotate(p_rbtree_node *root, p_rbtree_node x)
{
p_rbtree_node y = NULL;
y = x->left;
x->left = y->right;
if (y->right != nil)
y->right->p = x;
y->p = x->p;
if (x->p == nil)
*root = y;
else if (x == x->p->left)
x->p->left = y;
else
x->p->right = y;
y->right = x;
x->p = y;
return successed;
}
bool rbInsert(p_rbtree_node *root, p_rbtree_node z)
{
p_rbtree_node y = nil;
p_rbtree_node x = *root;
while (x != nil)
{
y = x;
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->p = y;
if (y == nil)
{
*root = z;
}
else if (z->key < y->key)
y->left = z;
else
y->right = z;
z->left = nil;
z->right = nil;
z->color = RED;
rbInsertFixup(root, z);
return successed;
}
bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z)
{
while (z->p->color == RED)
{
p_rbtree_node y = NULL;
if (z->p == z->p->p->left)
{
y = z->p->p->right;
if (y->color == RED)
{
z->p->color = BLACK;
y->color = BLACK;
z->p->p->color = RED;
z = z->p->p;
}
else if (z == z->p->right)
{
z = z->p;
leftRotate(root, z);
}
else
{
z->p->color = BLACK;
z->p->p->color = RED;
rightRotate(root, z->p->p);
}
}
else
{
y = z->p->p->left;
if (y->color == RED)
{
z->p->color = BLACK;
y->color = BLACK;
z->p->p->color = RED;
z = z->p->p;
}
else if (z == z->p->left)
{
z = z->p;
rightRotate(root, z);
}
else
{
z->p->color = BLACK;
z->p->p->color = RED;
leftRotate(root, z->p->p);
}
}
}
(*root)->color = BLACK;
return successed;
}
bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v)
{
if (u->p == nil)
{
*root = v;
}
else if (u == u->p->left)
{
u->p->left = v;
}
else
u->p->right = v;
v->p = u->p;
return successed;
}
p_rbtree_node treeMinimum(p_rbtree_node z)
{
while (z->left != nil)
z = z->left;
return z;
}
bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x)
{
p_rbtree_node w = nil;
while (x != nil && x->color == BLACK)
{
if (x == x->p->left)
{
w = x->p->right;
if (w->color == RED)
{
w->color = BLACK;
x->p->color = RED;
leftRotate(root, x->p);
w = x->p->right;
}
else if (w->right->color == BLACK && w->left->color == BLACK)
{
w->color = RED;
x = x->p;
}
else if (w->right->color == BLACK)
{
w->left->color = BLACK;
w->color = RED;
rightRotate(root, w);
w = x->p->right;
}
else
{
w->right->color = BLACK;
w->color = x->p->color;
w->p->color = BLACK;
leftRotate(root, x->p);
x = nil;
}
}
else
{
w = x->p->left;
if (w->color == RED)
{
w->color = BLACK;
x->p->color = RED;
rightRotate(root, x->p);
w = x->p->left;
}
else if (w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
x = x->p;
}
else if (w->left->color == BLACK)
{
w->color = RED;
w->right->color = BLACK;
leftRotate(root, w);
w = x->p->left;
}
else
{
w->color = RED;
w->left->color = BLACK;
w->p->color = BLACK;
rightRotate(root, x->p);
x = nil;
}
}
}
x->color = BLACK;
}
p_rbtree_node Delete(p_rbtree_node z)
{
return rbDelete(&root, z);
}
p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z)
{
p_rbtree_node y = nil, x = nil;
y = z;
int y_original_color = y->color;
if (z->left == nil)
{
x = z->right;
rbTransplant(root, z, x);
}
else if (z->right == nil)
{
x = z->left;
rbTransplant(root, z, x);
}
else
{
y = treeMinimum(z->right);
y_original_color = y->color;
x = y->right;
if (y->p == z)
{
x->p = y;
}
else
{
rbTransplant(root, y, x);
y->right = z->right;
z->right->p = y;
}
rbTransplant(root, z, y);
y->left = z->left;
y->left->p = y;
y->color = z->color;
}
if (y_original_color == BLACK)
rbDeleteFixup(root, x);
return z;
}
bool rbBuilt()
{
node.p = NULL;
node.left = NULL;
node.right = NULL;
node.key = -1;
node.color = BLACK;
root = nil;
p_rbtree_node n1 = getNode(n1);
n1->key = 1;
rbInsert(&root, n1);
p_rbtree_node n2 = getNode(n2);
n2->key = 2;
rbInsert(&root, n2);
p_rbtree_node n4 = getNode(n4);
n4->key = 4;
rbInsert(&root, n4);
p_rbtree_node n5 = getNode(n5);
n5->key = 5;
rbInsert(&root, n5);
p_rbtree_node n7 = getNode(n7);
n7->key = 7;
rbInsert(&root, n7);
p_rbtree_node n8 = getNode(n8);
n8->key = 8;
rbInsert(&root, n8);
p_rbtree_node n11 = getNode(n11);
n11->key = 11;
rbInsert(&root, n11);
p_rbtree_node n14 = getNode(n14);
n14->key = 14;
rbInsert(&root, n14);
p_rbtree_node n15 = getNode(n15);
n15->key = 15;
rbInsert(&root, n15);
return successed;
}
void rbDisplay(p_rbtree_node *root)
{
if (*root == nil)
return;
rbDisplay(&((*root)->left));
if ((*root)->color == RED)
printf("key=%d, color=RED\n", (*root)->key);
else
printf("key=%d, color=BLACK\n", (*root)->key);
rbDisplay(&((*root)->right));
}
void rbMidDisplay(p_rbtree_node *root)
{
if (*root == nil)
return;
if ((*root)->color == RED)
printf("key=%d, color=RED\n", (*root)->key);
else
printf("key=%d, color=BLACK\n", (*root)->key);
rbMidDisplay(&((*root)->left));
rbMidDisplay(&((*root)->right));
}
void Display(void)
{
rbDisplay(&root);
rbMidDisplay(&root);
}
test.c 测试文件
*
* =====================================================================================
*
* Filename: test.c
*
* Description:
*
* Version: 1.0
* Created: 2014年05月05日 11时34分19秒
* Revision: none
* Compiler: gcc
*
* Author: 我叫程序猿XXX
* Company:
*
* =====================================================================================
*/
#include "rbtree.h"
#include <stdio.h>
int main(void)
{
rbBuilt();
Display();
int key = 5;
p_rbtree_node node = Search(5);
p_rbtree_node temp = NULL;
temp = Delete(node);
printf("*******temp->key = %d**********\n", temp->key);
Display();
return 0;
}
代码的运行截图如下:
代码是通过先序和中序遍历得出的结果。
添加删除之后的运行结果如下:
我的编译系统是Linux,编译环境是gcc 版本 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC) 。后面将删除代码添加上。如果代码中有任何不对的地方,请大家指出,我好及时修改,谢谢大家。