无奈,书上所说的删除还没能领悟,以后补上吧
//RBTree.h
#ifndef _RBTREE_H_
#define _RBTREE_H_
#include <stdlib.h>
typedef int Element;
typedef enum
{
RED,
BLACK
}Color;
typedef struct _RBT_Node_
{
Color NodeColor;
Element data;
struct _RBT_Node_ *Parent;
struct _RBT_Node_ *LeftChild;
struct _RBT_Node_ *RightChild;
}RBT_Node;
typedef RBT_Node* RBT;
void InitRBT(RBT *tree);
RBT_Node* CreateNode(Element v, Color NodeColor);
bool InsertRBT(RBT *tree, Element v);
void RotateL(RBT *tree);
void RotateR(RBT *tree);
void TransColors(RBT *tree);
bool IsRed(RBT_Node *node);
//bool DeleteRBT(RBT *tree, Element v);
#endif //_RBTREE_H_//RBTree.cpp
#include "RBTree.h"
void InitRBT(RBT *tree)
{
*tree = NULL;
}
RBT_Node* CreateNode(Element v, Color NodeColor)
{
RBT_Node *p = (RBT_Node *)malloc(sizeof(RBT_Node));
if( NULL == p )
return NULL;
p->data = v;
p->LeftChild = NULL;
p->RightChild = NULL;
p->Parent = NULL;
p->NodeColor = NodeColor;
}
bool InsertRBT(RBT *tree, Element v)
{
RBT_Node *q = *tree;
RBT_Node *p = NULL;
RBT_Node *s = NULL;
if( NULL == *tree ) //根节点为黑节点
{
*tree = CreateNode(v, BLACK);
if( NULL == *tree )
return false;
}
else
{
while ( NULL != q) //寻找插入位置
{
p = q; //记录路径
if( q->data > v )
q = q->LeftChild;
else if( q->data < v )
q = q->RightChild;
else
return false;
}
q = CreateNode(v, RED);
if( NULL == q )
return false;
if( p->data > v ) //连接新节点
p->LeftChild = q;
else
p->RightChild = q;
q->Parent = p;
while (NULL != p) //从新节点的父节点开始向上回溯,准备调整各种不符合定义的红链接,因为红色存在上传的可能,所以需要尽可能回溯
{
s = p->Parent;
if( !IsRed(p->LeftChild) && IsRed(p->RightChild) ) //仅右孩子是红
RotateL(&p);
if( IsRed(p->LeftChild) && IsRed(p->LeftChild->LeftChild) ) //左孩子即左孙子都红,短路法则保证不会对NULL进行->操作
RotateR(&p);
if( IsRed(p->LeftChild) && IsRed(p->RightChild) ) //左右孩子都红
TransColors(&p);
if( NULL == s ) //旋转函数前p为整棵树的根,修改新根
*tree = p;
p = p->Parent; //回溯
}
}
}
bool IsRed(RBT_Node *node)
{
if( NULL == node )
return false;
return RED == node->NodeColor;
}
void TransColors(RBT *tree)
{
if( NULL == (*tree)->Parent )
(*tree)->NodeColor = BLACK; //树根必须为黑
else
(*tree)->NodeColor = RED;
(*tree)->LeftChild->NodeColor = BLACK;
(*tree)->RightChild->NodeColor = BLACK;
}
void RotateL(RBT *tree) //左旋转
{
RBT_Node *pp = (*tree)->Parent;
RBT_Node *p = (*tree)->RightChild;
RBT_Node *c = *tree;
c->RightChild = p->LeftChild; //保存p可能出现的左孩子
if( NULL != p->LeftChild )
p->LeftChild->Parent = c;
p->LeftChild = c; //旋转
c->Parent = p;
p->NodeColor = c->NodeColor; //交换节点颜色
c->NodeColor = RED;
if( NULL != pp && pp->LeftChild == c ) //重新连接到外部
pp->LeftChild = p;
if( NULL != pp && pp->RightChild == c )
pp->RightChild = p;
p->Parent = pp;
*tree = p;
}
void RotateR(RBT *tree)
{
RBT_Node *pp = (*tree)->Parent;
RBT_Node *p = (*tree)->LeftChild;
RBT_Node *c = *tree;
c->LeftChild = p->RightChild;
if( NULL != p->RightChild )
p->RightChild->Parent = c;
p->RightChild = c;
c->Parent = p;
p->NodeColor = c->NodeColor;
c->NodeColor = RED;
if( pp != NULL && pp->LeftChild == c )
pp->LeftChild = p;
if (pp != NULL && pp->RightChild == c)
pp->RightChild = p;
p->Parent = pp;
*tree = p;
}
/*
bool DeleteRBT(RBT *tree, Element v)
{
RBT_Node *q = *tree;
RBT_Node *p = NULL;
while (NULL != q) //寻找
{
if( v == q->data )
break;
else if( v > q->data )
q = q->RightChild;
else
q = q->LeftChild;
}
if( NULL == q ) //根为空或节点不存在
return false;
if( NULL != q->LeftChild && NULL != q->RightChild ) //存在左右孩子,转化为只有一个孩子的情况
{
p = q->RightChild;
while (NULL != p->LeftChild) //寻找右子树中最小节点
p = p->LeftChild;
q->data = p->data; //替换
q = p;
}
}
*///main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "RBTree.h"
int main(int argc, char **argv)
{
RBT tree;
// Element Array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Element Array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int num = sizeof(Array) / sizeof(Element);
InitRBT(&tree);
for(int i= 0; i < num; i++)
InsertRBT(&tree, Array[i]);
system("pause");
}
1879

被折叠的 条评论
为什么被折叠?



