// red_black_tree.cpp : 定义控制台应用程序的入口点。
//
/*
** red_black_tree.cpp
** 主要功能:创建一颗红黑树
** 数据结构:基本的数据结构是使用双向链表(需要经常访问PARENT,GRANDPARENT and UNCLE)实现的二叉树
** 核心步骤:在插入时红黑树的3*2种状态
** PARENT IS LEFT
** case1:PARENT is red && UNCLE is red
** case2: PARENT is red && UNCLE is black && x is RIGHTCHILD
** case3: PARENT is red && UNCLE is black && x is LEFTCHILD
** PARENT IS RIGHT
** case4: <->case1
** case5: <->case2
** case6: <->case3
**
*/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* time */
#define PARENT(X) X->parent
#define GRANDPARENT(X) X->parent->parent
#define UNCLE(X) (PARENT(X) == GRANDPARENT(X)->left ? GRANDPARENT(X)->right : GRANDPARENT(X)->left)
#define ISLEFT(X) (PARENT(X)->left == X ? 1 : 0)
#define ISRIGHT(X) (PARENT(X)->right == X ? 1 : 0)
typedef int key_t;
typedef struct node_t{
key_t key;
char color;
struct node_t * left;
struct node_t * right;
struct node_t * parent;
};
typedef node_t node_t;
typedef struct rbt{
node_t * root;
int nodes;
};
typedef rbt rbtree;
rbtree * init_rbtree();
node_t * get_empty_node();
node_t * make_node_key(key_t key);
int insert(rbtree * rbt_p, key_t key);
rbtree * init_rbtree()
{
rbtree * rbt_p = NULL;
rbt_p = (rbtree *) malloc(sizeof(rbtree));
rbt_p->root = NULL;
rbt_p->nodes = 0;
return rbt_p;
}
node_t * get_empty_node()
{
node_t * result = NULL;
result = (node_t *)malloc(sizeof(node_t));
result->key = -1;
result->color = 'R';
result->left = NULL;
result->right = NULL;
result->parent = NULL;
return result;
}
node_t * make_node_key(key_t key)
{
node_t * result = NULL;
result = (node_t *)malloc(sizeof(node_t));
result->key = key;
result->color = 'R';
result->left = NULL;
result->right = NULL;
result->parent = NULL;
return result;
}
node_t * insert(node_t * root, key_t key)
{
node_t * tmp_node = NULL;
if(root == NULL)
{
tmp_node = make_node_key(key);
return tmp_node;
}
if(key < root->key)
{
if(root->left == NULL)
{
tmp_node = make_node_key(key);
root->left = tmp_node;
tmp_node->parent = root;
}
else
tmp_node = insert(root->left, key);
}
else if(key >= root->key)
{
if(root->right == NULL)
{
tmp_node = make_node_key(key);
root->right = tmp_node;
tmp_node->parent = root;
}
else
tmp_node = insert(root->right, key);
}
return tmp_node;
}
int left_rotate(node_t * node_x)
{
node_t * tmp_node = NULL;
tmp_node = PARENT(node_x);
if(PARENT(tmp_node) != NULL) //注意对根结点的特殊处理
{
if(ISLEFT(PARENT(node_x))) //需要根据父节点是左孩子还是右孩子,决定旋转之后的结点作为左孩子,还是又孩子插入
{
PARENT(tmp_node)->left = node_x;
}
else if(ISRIGHT(PARENT(node_x))) //需要根据父节点是左孩子还是右孩子,决定旋转之后的结点作为左孩子,还是又孩子插入
{
PARENT(tmp_node)->right = node_x;
}
}
PARENT(node_x) = PARENT(tmp_node);
if(node_x->left != NULL) //对于叶子结点不需要为其指定父节点,因为叶子结点是一个NULL,没有存储空间
PARENT(node_x->left) = tmp_node;
tmp_node->right = node_x->left;
PARENT(tmp_node) = node_x;
node_x->left = tmp_node;
return 1;
}
int right_rotate(node_t * node_x)
{
node_t * tmp_node = NULL;
tmp_node = PARENT(node_x);
tmp_node->left = node_x->right;
if(node_x->right != NULL)
PARENT(node_x->right) = tmp_node;
if(PARENT(tmp_node) != NULL) //注意对根结点的特殊处理
{
if(ISLEFT(PARENT(node_x))) //需要根据父节点是左孩子还是右孩子,决定旋转之后的结点作为左孩子,还是又孩子插入
{
PARENT(tmp_node)->left = node_x;
}
else if(ISRIGHT(PARENT(node_x))) //需要根据父节点是左孩子还是右孩子,决定旋转之后的结点作为左孩子,还是又孩子插入
{
PARENT(tmp_node)->right = node_x;
}
}
PARENT(node_x) = PARENT(tmp_node);
PARENT(tmp_node) = node_x;
node_x->right = tmp_node;
return 1;
}
node_t * adjust(node_t * node_x)
{
node_t * root = NULL;
if(node_x->parent == NULL) // the node_x is root
{
node_x->color = 'B';
root = node_x;
return root;
}
while(node_x->parent->color == 'R') //node_x->parent->color=='B' garentee that the node_x's parent is not root.
{
if(ISLEFT(PARENT(node_x)))
{
if(UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'R')
{
PARENT(node_x)->color = 'B';
UNCLE(node_x)->color = 'B';
GRANDPARENT(node_x)->color = 'R';
node_x = GRANDPARENT(node_x);
}
else if(UNCLE(node_x) == NULL && ISRIGHT(node_x) == 1 || UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'B' && ISRIGHT(node_x) == 1)
{
left_rotate(node_x);
node_x = node_x->left;
}
else if(UNCLE(node_x) == NULL && ISLEFT(node_x) == 1 || UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'B' && ISLEFT(node_x) == 1)
{
right_rotate(PARENT(node_x));
PARENT(node_x)->color = 'B';
PARENT(node_x)->right->color = 'R';
if(GRANDPARENT(node_x) == NULL)
{
root = PARENT(node_x);
}
}
}
else if(ISRIGHT(PARENT(node_x)))
{
if(UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'R')
{
PARENT(node_x)->color = 'B';
UNCLE(node_x)->color = 'B';
GRANDPARENT(node_x)->color = 'R';
node_x = GRANDPARENT(node_x);
}
else if(UNCLE(node_x) == NULL && ISLEFT(node_x) == 1 || UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'B' && ISLEFT(node_x) == 1)
{
right_rotate(node_x);
node_x = node_x->right;
}
else if(UNCLE(node_x) == NULL && ISRIGHT(node_x) == 1 || UNCLE(node_x) != NULL && UNCLE(node_x)->color == 'B' && ISRIGHT(node_x) == 1)
{
left_rotate(PARENT(node_x));
PARENT(node_x)->color = 'B';
PARENT(node_x)->left->color = 'R';
if(GRANDPARENT(node_x) == NULL)
{
root = PARENT(node_x);
}
}
}
if(PARENT(node_x) == NULL)
{
node_x->color = 'B';
root = node_x;
break;
}
}
return root;
}
int insert_rbtree(rbtree * rbt_t, key_t key)
{
node_t * tmp_node = NULL;
node_t * node_x = NULL;
node_t * root = NULL;
if(rbt_t->root == NULL)
{
tmp_node = make_node_key(key);
tmp_node->color = 'B';
rbt_t->root = tmp_node;
rbt_t->nodes ++;
}
else
{
node_x = insert(rbt_t->root, key);
rbt_t->nodes ++;
root = adjust(node_x);
if(root != NULL)
rbt_t->root = root;
}
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
rbtree * rbt_t = NULL;
rbt_t = init_rbtree();
int i, j;
for(i=18; i>0; --i)
{
srand (time(NULL));
j = rand();
insert_rbtree(rbt_t, j%10);
}
return 1;
}