You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

669 lines
15 KiB

/**
* C<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ֵĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(Red Black Tree)
*
* @author skywang
* @date 2013/11/18
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include "rbtree.h"
#define rb_parent(r) ((r)->parent)
#define rb_color(r) ((r)->color)
#define rb_is_red(r) ((r)->color==RED)
#define rb_is_black(r) ((r)->color==BLACK)
#define rb_set_black(r) do { (r)->color = BLACK; } while (0)
#define rb_set_red(r) do { (r)->color = RED; } while (0)
#define rb_set_parent(r,p) do { (r)->parent = (p); } while (0)
#define rb_set_color(r,c) do { (r)->color = (c); } while (0)
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>"<EFBFBD><EFBFBD>
*/
RBRoot* create_rbtree()
{
RBRoot *root = (RBRoot *)malloc(sizeof(RBRoot));
root->node = NULL;
return root;
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
*/
int ListTraverse(LinkList L)
{
LinkList p = L->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return 1;
}
static void inorder(RBTree tree)
{
if (tree != NULL)
{
inorder(tree->left);
printf("%s:", tree->key.filename);
ListTraverse(tree->key.index);
inorder(tree->right);
}
}
void inorder_rbtree(RBRoot *root)
{
if (root)
inorder(root->node);
}
/*
* (<EFBFBD>ݹ<EFBFBD>ʵ<EFBFBD><EFBFBD>)<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x"<EFBFBD>м<EFBFBD>ֵΪkey<EFBFBD>Ľڵ<EFBFBD>
*/
static Node* search(RBTree x, int key)
{
if (x == NULL || x->key.hashfile == key)
return x;
if (key < x->key.hashfile)
return search(x->left, key);
else
return search(x->right, key);
}
RBleaf* rbtree_search(RBRoot *root, int key)
{
if (root) {
Node* temp = search(root->node, key);
if ( temp!= NULL)
{
return &temp->key;
}
}
return NULL;
}
/*
* <EFBFBD>ҽ<EFBFBD><EFBFBD><EFBFBD>(x)<EFBFBD>ĺ<EFBFBD><EFBFBD>̽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD>ڸý<EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>
*/
static Node* rbtree_successor(RBTree x)
{
// <20><><EFBFBD><EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA>ӣ<EFBFBD><D3A3><EFBFBD>"x<>ĺ<EFBFBD><C4BA>̽<EFBFBD><CCBD><EFBFBD>"Ϊ "<22><><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>"<22><>
if (x->right != NULL)
return minimum(x->right);
// <20><><EFBFBD><EFBFBD><78><C3BB><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD><D3A1><EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><D6BF>ܣ<EFBFBD>
// (01) x<><78>"һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD>"x<>ĺ<EFBFBD><C4BA>̽<EFBFBD><CCBD><EFBFBD>"Ϊ "<22><><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>"<22><>
// (02) x<><78>"һ<><D2BB><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"x<><78><EFBFBD><EFBFBD><EFBFBD>͵ĸ<CDB5><C4B8><EFBFBD><EFBFBD><EFBFBD><E3A3AC><EFBFBD>Ҹø<D2B8><C3B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD>͵ĸ<CDB5><C4B8><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD>"x<>ĺ<EFBFBD><C4BA>̽<EFBFBD><CCBD><EFBFBD>"<22><>
Node* y = x->parent;
while ((y != NULL) && (x == y->right))
{
x = y;
y = y->parent;
}
return y;
}
/*
* <EFBFBD>ҽ<EFBFBD><EFBFBD><EFBFBD>(x)<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵС<EFBFBD>ڸý<EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>
*/
static Node* rbtree_predecessor(RBTree x)
{
// <20><><EFBFBD><EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>"x<><78>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"Ϊ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><>
if (x->left != NULL)
return maximum(x->left);
// <20><><EFBFBD><EFBFBD><78><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><D6BF>ܣ<EFBFBD>
// (01) x<><78>"һ<><D2BB><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>"<22><><EFBFBD><EFBFBD>"x<><78>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"Ϊ "<22><><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>"<22><>
// (01) x<><78>"һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"x<><78><EFBFBD><EFBFBD><EFBFBD>͵ĸ<CDB5><C4B8><EFBFBD><EFBFBD><EFBFBD><E3A3AC><EFBFBD>Ҹø<D2B8><C3B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>"<22><><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD>͵ĸ<CDB5><C4B8><EFBFBD><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD>"x<><78>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22><>
Node* y = x->parent;
while ((y != NULL) && (x == y->left))
{
x = y;
y = y->parent;
}
return y;
}
/*
* <EFBFBD>Ժ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<EFBFBD>(x)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ͼ(<EFBFBD>Խڵ<EFBFBD>x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<EFBFBD><EFBFBD>
* px px
* / /
* x y
* / \ --(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>)--> / \ #
* lx y x ry
* / \ / \
* ly ry lx ly
*
*
*/
static void rbtree_left_rotate(RBRoot *root, Node *x)
{
// <20><><EFBFBD><EFBFBD>x<EFBFBD><78><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>Ϊy
Node *y = x->right;
// <20><> <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD> <20><>Ϊ <20><>x<EFBFBD><78><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD><D3A1><EFBFBD>
// <20><><EFBFBD><EFBFBD>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӷǿգ<C7BF><D5A3><EFBFBD> <20><>x<EFBFBD><78> <20><>Ϊ <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĸ<D3B5><C4B8>ס<EFBFBD>
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
// <20><> <20><>x<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20><>Ϊ <20><>y<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD>
y->parent = x->parent;
if (x->parent == NULL)
{
//tree = y; // <20><><EFBFBD><EFBFBD> <20><>x<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20>ǿսڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>y<EFBFBD><79>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>
root->node = y; // <20><><EFBFBD><EFBFBD> <20><>x<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20>ǿսڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>y<EFBFBD><79>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>
}
else
{
if (x->parent->left == x)
x->parent->left = y; // <20><><EFBFBD><EFBFBD> x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>y<EFBFBD><79>Ϊ<EFBFBD><CEAA>x<EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
else
x->parent->right = y; // <20><><EFBFBD><EFBFBD> x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>y<EFBFBD><79>Ϊ<EFBFBD><CEAA>x<EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
}
// <20><> <20><>x<EFBFBD><78> <20><>Ϊ <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
y->left = x;
// <20><> <20><>x<EFBFBD>ĸ<EFBFBD><C4B8>ڵ㡱 <20><>Ϊ <20><>y<EFBFBD><79>
x->parent = y;
}
/*
* <EFBFBD>Ժ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<EFBFBD>(y)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ͼ(<EFBFBD>Խڵ<EFBFBD>y<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<EFBFBD><EFBFBD>
* py py
* / /
* y x
* / \ --(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>)--> / \ #
* x ry lx y
* / \ / \ #
* lx rx rx ry
*
*/
static void rbtree_right_rotate(RBRoot *root, Node *y)
{
// <20><><EFBFBD><EFBFBD>x<EFBFBD>ǵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
Node *x = y->left;
// <20><> <20><>x<EFBFBD><78><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD> <20><>Ϊ <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD>
// <20><><EFBFBD><EFBFBD>"x<><78><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>"<22><>Ϊ<EFBFBD>յĻ<D5B5><C4BB><EFBFBD><EFBFBD><EFBFBD> <20><>y<EFBFBD><79> <20><>Ϊ <20><>x<EFBFBD><78><EFBFBD>Һ<EFBFBD><D2BA>ӵĸ<D3B5><C4B8>ס<EFBFBD>
y->left = x->right;
if (x->right != NULL)
x->right->parent = y;
// <20><> <20><>y<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20><>Ϊ <20><>x<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD>
x->parent = y->parent;
if (y->parent == NULL)
{
//tree = x; // <20><><EFBFBD><EFBFBD> <20><>y<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20>ǿսڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>x<EFBFBD><78>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>
root->node = x; // <20><><EFBFBD><EFBFBD> <20><>y<EFBFBD>ĸ<EFBFBD><C4B8>ס<EFBFBD> <20>ǿսڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>x<EFBFBD><78>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>
}
else
{
if (y == y->parent->right)
y->parent->right = x; // <20><><EFBFBD><EFBFBD> y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>x<EFBFBD><78>Ϊ<EFBFBD><CEAA>y<EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD>
else
y->parent->left = x; // (y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><>x<EFBFBD><78>Ϊ<EFBFBD><CEAA>x<EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
}
// <20><> <20><>y<EFBFBD><79> <20><>Ϊ <20><>x<EFBFBD><78><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD>
x->right = y;
// <20><> <20><>y<EFBFBD>ĸ<EFBFBD><C4B8>ڵ㡱 <20><>Ϊ <20><>x<EFBFBD><78>
y->parent = x;
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>֮<EFBFBD><EFBFBD>(ʧȥƽ<EFBFBD><EFBFBD>)<EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD><EFBFBD>øú<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* Ŀ<EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* root <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>
* node <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> // <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><E3B7A8><EFBFBD>ۡ<EFBFBD><DBA1>е<EFBFBD>z
*/
static void rbtree_insert_fixup(RBRoot *root, Node *node)
{
Node *parent, *gparent;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>Ҹ<EFBFBD><D2B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
while ((parent = rb_parent(node)) && rb_is_red(parent))
{
gparent = rb_parent(parent);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㡱<DAB5>ǡ<EFBFBD><C7A1><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
if (parent == gparent->left)
{
// Case 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>Ǻ<EFBFBD>ɫ
{
Node *uncle = gparent->right;
if (uncle && rb_is_red(uncle))
{
rb_set_black(uncle);
rb_set_black(parent);
rb_set_red(gparent);
node = gparent;
continue;
}
}
// Case 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ҵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>
if (parent->right == node)
{
Node *tmp;
rbtree_left_rotate(root, parent);
tmp = parent;
parent = node;
node = tmp;
}
// Case 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ҵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
rb_set_black(parent);
rb_set_red(gparent);
rbtree_right_rotate(root, gparent);
}
else//<2F><><EFBFBD><EFBFBD>z<EFBFBD>ĸ<EFBFBD><C4B8>ڵ㡱<DAB5>ǡ<EFBFBD>z<EFBFBD><7A><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD>
{
// Case 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>Ǻ<EFBFBD>ɫ
{
Node *uncle = gparent->left;
if (uncle && rb_is_red(uncle))
{
rb_set_black(uncle);
rb_set_black(parent);
rb_set_red(gparent);
node = gparent;
continue;
}
}
// Case 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ҵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (parent->left == node)
{
Node *tmp;
rbtree_right_rotate(root, parent);
tmp = parent;
parent = node;
node = tmp;
}
// Case 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ҵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD>
rb_set_black(parent);
rb_set_red(gparent);
rbtree_left_rotate(root, gparent);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Ϊ<EFBFBD><CEAA>ɫ
rb_set_black(root->node);
}
/*
* <EFBFBD><EFBFBD><EFBFBD>ӽڵ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>(node)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* root <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>
* node <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> // <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><E3B7A8><EFBFBD>ۡ<EFBFBD><DBA1>е<EFBFBD>z
*/
static void rbtree_insert(RBRoot *root, Node *node)
{
Node *y = NULL;
Node *x = root->node;
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
while (x != NULL)
{
y = x;
if (node->key.hashfile < x->key.hashfile)
x = x->left;
else
x = x->right;
}
rb_parent(node) = y;
if (y != NULL)
{
if (node->key.hashfile < y->key.hashfile)
y->left = node; // <20><><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5> < <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>node<64><65>Ϊ<EFBFBD><CEAA>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
else
y->right = node; // <20><><EFBFBD><EFBFBD>3<EFBFBD><33>(<28><>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5> >= <20><>y<EFBFBD><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>)<29><>node<64><65>Ϊ<EFBFBD><CEAA>y<EFBFBD><79><EFBFBD>Һ<EFBFBD><D2BA>ӡ<EFBFBD>
}
else
{
root->node = node; // <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD>y<EFBFBD>ǿսڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>node<64><65>Ϊ<EFBFBD><CEAA>
}
// 2. <20><><EFBFBD>ýڵ<C3BD><DAB5><EFBFBD><EFBFBD><EFBFBD>ɫΪ<C9AB><CEAA>ɫ
node->color = RED;
// 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<CEAA>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rbtree_insert_fixup(root, node);
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* key <EFBFBD>Ǽ<EFBFBD>ֵ<EFBFBD><EFBFBD>
* parent <EFBFBD>Ǹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* left <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
* right <EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ӡ<EFBFBD>
*/
static Node* create_rbtree_node(RBleaf key, Node *parent, Node *left, Node* right)
{
Node* p;
if ((p = (Node *)malloc(sizeof(Node))) == NULL)
return NULL;
p->key = key;
p->left = left;
p->right = right;
p->parent = parent;
p->color = BLACK; // Ĭ<><C4AC>Ϊ<EFBFBD><CEAA>ɫ
return p;
}
/*
* <EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD>ֵΪkey)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* root <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>
* key <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ֵ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>
* 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
* -1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*/
int insert_rbtree(RBRoot *root, RBleaf key)
{
Node *node; // <20>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ֵ<EFBFBD>Ľڵ㡣
// (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ֵ<EFBFBD>Ľڵ㣬ע<E3A3AC>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBB0><EFBFBD>ɣ<EFBFBD>)
if (search(root->node, key.hashfile) != NULL)
return -1;
// <20><><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3>򷵻ء<F2B7B5BB>
if ((node = create_rbtree_node(key, NULL, NULL, NULL)) == NULL)
return -1;
rbtree_insert(root, node);
return 0;
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD>ڴӺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>֮<EFBFBD><EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧȥƽ<EFBFBD><EFBFBD>)<EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD><EFBFBD>øú<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* Ŀ<EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* root <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>
* node <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<EFBFBD>
*/
static void rbtree_delete_fixup(RBRoot *root, Node *node, Node *parent)
{
Node *other;
while ((!node || rb_is_black(node)) && node != root->node)
{
if (parent->left == node)
{
other = parent->right;
if (rb_is_red(other))
{
// Case 1: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_black(other);
rb_set_red(parent);
rbtree_left_rotate(root, parent);
other = parent->right;
}
if ((!other->left || rb_is_black(other->left)) &&
(!other->right || rb_is_black(other->right)))
{
// Case 2: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_red(other);
node = parent;
parent = rb_parent(node);
}
else
{
if (!other->right || rb_is_black(other->right))
{
// Case 3: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB>
rb_set_black(other->left);
rb_set_red(other);
rbtree_right_rotate(root, other);
other = parent->right;
}
// Case 4: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_color(other, rb_color(parent));
rb_set_black(parent);
rb_set_black(other->right);
rbtree_left_rotate(root, parent);
node = root->node;
break;
}
}
else
{
other = parent->left;
if (rb_is_red(other))
{
// Case 1: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_black(other);
rb_set_red(parent);
rbtree_right_rotate(root, parent);
other = parent->left;
}
if ((!other->left || rb_is_black(other->left)) &&
(!other->right || rb_is_black(other->right)))
{
// Case 2: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_red(other);
node = parent;
parent = rb_parent(node);
}
else
{
if (!other->left || rb_is_black(other->left))
{
// Case 3: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB>
rb_set_black(other->right);
rb_set_red(other);
rbtree_left_rotate(root, other);
other = parent->left;
}
// Case 4: x<><78><EFBFBD>ֵ<EFBFBD>w<EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
rb_set_color(other, rb_color(parent));
rb_set_black(parent);
rb_set_black(other->left);
rbtree_right_rotate(root, parent);
node = root->node;
break;
}
}
}
if (node)
rb_set_black(node);
}
/*
* ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* tree <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* node ɾ<EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD>
*/
void rbtree_delete(RBRoot *root, Node *node)
{
Node *child, *parent;
int color;
// <20><>ɾ<EFBFBD><C9BE><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>"<22><><EFBFBD>Һ<EFBFBD><D2BA>Ӷ<EFBFBD><D3B6><EFBFBD>Ϊ<EFBFBD><CEAA>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((node->left != NULL) && (node->right != NULL))
{
// <20><>ɾ<EFBFBD>ڵ<EFBFBD><DAB5>ĺ<EFBFBD><C4BA>̽ڵ㡣(<28><>Ϊ"ȡ<><C8A1><EFBFBD>ڵ<EFBFBD>")
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>"<22><>ɾ<EFBFBD>ڵ<EFBFBD>"<22><>λ<EFBFBD>ã<EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD>ٽ<EFBFBD>"<22><>ɾ<EFBFBD>ڵ<EFBFBD><><C8A5><EFBFBD><EFBFBD>
Node *replace = node;
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>̽ڵ<CCBD>
replace = replace->right;
while (replace->left != NULL)
replace = replace->left;
// "node<64>ڵ<EFBFBD>"<22><><EFBFBD>Ǹ<EFBFBD><C7B8>ڵ<EFBFBD><>и<EFBFBD><D0B8>ڵ㲻<DAB5><E3B2BB><EFBFBD>ڸ<EFBFBD><DAB8>ڵ<EFBFBD>)
if (rb_parent(node))
{
if (rb_parent(node)->left == node)
rb_parent(node)->left = replace;
else
rb_parent(node)->right = replace;
}
else
// "node<64>ڵ<EFBFBD>"<22>Ǹ<EFBFBD><C7B8>ڵ㣬<DAB5><E3A3AC><EFBFBD>¸<EFBFBD><C2B8>ڵ㡣
root->node = replace;
// child<6C><64><><C8A1><EFBFBD>ڵ<EFBFBD>"<22><><EFBFBD>Һ<EFBFBD><D2BA>ӣ<EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD>Ҫ"<22><><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>"<22><>
// "ȡ<><C8A1><EFBFBD>ڵ<EFBFBD>"<22>϶<EFBFBD><CFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>̽ڵ㡣
child = replace->right;
parent = rb_parent(replace);
// <20><><EFBFBD><EFBFBD><><C8A1><EFBFBD>ڵ<EFBFBD>"<22><><EFBFBD><EFBFBD>ɫ
color = rb_color(replace);
// "<22><>ɾ<EFBFBD><C9BE><EFBFBD>ڵ<EFBFBD>"<22><>"<22><><EFBFBD>ĺ<EFBFBD><C4BA>̽ڵ<CCBD><DAB5>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>"
if (parent == node)
{
parent = replace;
}
else
{
// child<6C><64>Ϊ<EFBFBD><CEAA>
if (child)
rb_set_parent(child, parent);
parent->left = child;
replace->right = node->right;
rb_set_parent(node->right, replace);
}
replace->parent = node->parent;
replace->color = node->color;
replace->left = node->left;
node->left->parent = replace;
if (color == BLACK)
rbtree_delete_fixup(root, child, parent);
free(node);
return;
}
if (node->left != NULL)
child = node->left;
else
child = node->right;
parent = node->parent;
// <20><><EFBFBD><EFBFBD><><C8A1><EFBFBD>ڵ<EFBFBD>"<22><><EFBFBD><EFBFBD>ɫ
color = node->color;
if (child)
child->parent = parent;
// "node<64>ڵ<EFBFBD>"<22><><EFBFBD>Ǹ<EFBFBD><C7B8>ڵ<EFBFBD>
if (parent)
{
if (parent->left == node)
parent->left = child;
else
parent->right = child;
}
else
root->node = child;
if (color == BLACK)
rbtree_delete_fixup(root, child, parent);
free(node);
}
/*
* ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵΪkey<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* tree <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* key <EFBFBD><EFBFBD>ֵ
*/
void delete_rbtree(RBRoot *root, RBleaf key)
{
Node *z, *node;
if ((z = search(root->node, key.hashfile)) != NULL)
rbtree_delete(root, z);
}
/*
* <EFBFBD><EFBFBD><EFBFBD>ٺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void rbtree_destroy(RBTree tree)
{
if (tree == NULL)
return;
if (tree->left != NULL)
rbtree_destroy(tree->left);
if (tree->right != NULL)
rbtree_destroy(tree->right);
free(tree);
}
void destroy_rbtree(RBRoot *root)
{
if (root != NULL)
rbtree_destroy(root->node);
free(root);
}
/*
* <EFBFBD><EFBFBD>ӡ"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
*
* tree -- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<EFBFBD>
* key -- <EFBFBD>ڵ<EFBFBD><EFBFBD>ļ<EFBFBD>ֵ
* direction -- 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>ýڵ<EFBFBD><EFBFBD>Ǹ<EFBFBD><EFBFBD>ڵ<EFBFBD>;
* -1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>ýڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
* 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>ýڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ӡ<EFBFBD>
*/
static void rbtree_print(RBTree tree, RBleaf key, int direction)
{
if (tree != NULL)
{
if (direction == 0) // tree<65>Ǹ<EFBFBD><C7B8>ڵ<EFBFBD>
printf("%2d(B) is root\n", tree->key);
else // tree<65>Ƿ<EFBFBD>֧<EFBFBD>ڵ<EFBFBD>
printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree) ? "R" : "B", key, direction == 1 ? "right" : "left");
rbtree_print(tree->left, tree->key, -1);
rbtree_print(tree->right, tree->key, 1);
}
}
void print_rbtree(RBRoot *root)
{
if (root != NULL && root->node != NULL)
rbtree_print(root->node, root->node->key, 0);
}