more code
This commit is contained in:
parent
c1462d726a
commit
ffa5812053
|
@ -44,8 +44,9 @@ SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
||||||
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter);
|
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter);
|
||||||
|
|
||||||
// STRUCT =============================================
|
// STRUCT =============================================
|
||||||
|
typedef enum { RED, BLACK } ECOLOR;
|
||||||
struct SRBTreeNode {
|
struct SRBTreeNode {
|
||||||
enum { RED, BLACK } color;
|
ECOLOR color;
|
||||||
SRBTreeNode *parent;
|
SRBTreeNode *parent;
|
||||||
SRBTreeNode *left;
|
SRBTreeNode *left;
|
||||||
SRBTreeNode *right;
|
SRBTreeNode *right;
|
||||||
|
|
|
@ -18,46 +18,40 @@
|
||||||
#define RBTREE_NODE_COLOR(N) ((N) ? (N)->color : BLACK)
|
#define RBTREE_NODE_COLOR(N) ((N) ? (N)->color : BLACK)
|
||||||
|
|
||||||
// SRBTree ================================================
|
// SRBTree ================================================
|
||||||
static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *pNode) {
|
static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
SRBTreeNode *right = pNode->right;
|
SRBTreeNode *y = x->right;
|
||||||
|
x->right = y->left;
|
||||||
pNode->right = right->left;
|
if (y->left) {
|
||||||
if (pNode->right) {
|
y->left->parent = x;
|
||||||
pNode->right->parent = pNode;
|
|
||||||
}
|
}
|
||||||
|
y->parent = x->parent;
|
||||||
right->parent = pNode->parent;
|
if (x->parent == NULL) {
|
||||||
if (pNode->parent == NULL) {
|
pTree->rootNode = y;
|
||||||
pTree->rootNode = right;
|
} else if (x == x->parent->left) {
|
||||||
} else if (pNode == pNode->parent->left) {
|
x->parent->left = y;
|
||||||
pNode->parent->left = right;
|
|
||||||
} else {
|
} else {
|
||||||
pNode->parent->right = right;
|
x->parent->right = y;
|
||||||
}
|
}
|
||||||
|
y->left = x;
|
||||||
right->left = pNode;
|
x->parent = y;
|
||||||
pNode->parent = right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *pNode) {
|
static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
SRBTreeNode *left = pNode->left;
|
SRBTreeNode *y = x->left;
|
||||||
|
x->left = y->right;
|
||||||
pNode->left = left->right;
|
if (y->right) {
|
||||||
if (pNode->left) {
|
y->right->parent = x;
|
||||||
pNode->left->parent = pNode;
|
|
||||||
}
|
}
|
||||||
|
y->parent = x->parent;
|
||||||
left->parent = pNode->parent;
|
if (x->parent == NULL) {
|
||||||
if (pNode->parent == NULL) {
|
pTree->rootNode = y;
|
||||||
pTree->rootNode = left;
|
} else if (x == x->parent->left) {
|
||||||
} else if (pNode == pNode->parent->left) {
|
x->parent->left = y;
|
||||||
pNode->parent->left = left;
|
|
||||||
} else {
|
} else {
|
||||||
pNode->parent->right = left;
|
x->parent->right = y;
|
||||||
}
|
}
|
||||||
|
y->right = x;
|
||||||
left->right = pNode;
|
x->parent = y;
|
||||||
pNode->parent = left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRBTreeNode *tRBTreeSuccessor(SRBTreeNode *pNode) {
|
static SRBTreeNode *tRBTreeSuccessor(SRBTreeNode *pNode) {
|
||||||
|
@ -200,50 +194,114 @@ SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode) {
|
static void tRBTreeTransplant(SRBTree *pTree, SRBTreeNode *u, SRBTreeNode *v) {
|
||||||
// update min/max node
|
if (u->parent == NULL) {
|
||||||
if (pTree->minNode == pNode) {
|
pTree->rootNode = v;
|
||||||
pTree->minNode = tRBTreeSuccessor(pTree->minNode);
|
} else if (u == u->parent->left) {
|
||||||
|
u->parent->left = v;
|
||||||
|
} else {
|
||||||
|
u->parent->right = v;
|
||||||
}
|
}
|
||||||
if (pTree->maxNode == pNode) {
|
if (v) {
|
||||||
pTree->maxNode = tRBTreePredecessor(pTree->maxNode);
|
v->parent = u->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tRBTreeDropFixup(SRBTree *t, SRBTreeNode *x) {
|
||||||
|
while (x != t->rootNode && x->color == BLACK) {
|
||||||
|
if (x == x->parent->left) {
|
||||||
|
SRBTreeNode *w = x->parent->right;
|
||||||
|
if (RBTREE_NODE_COLOR(w) == RED) {
|
||||||
|
w->color = BLACK;
|
||||||
|
x->parent->color = RED;
|
||||||
|
tRBTreeRotateLeft(t, x->parent);
|
||||||
|
w = x->parent->right;
|
||||||
|
}
|
||||||
|
if (RBTREE_NODE_COLOR(w->left) == BLACK && RBTREE_NODE_COLOR(w->right) == BLACK) {
|
||||||
|
w->color = RED;
|
||||||
|
x = x->parent;
|
||||||
|
} else {
|
||||||
|
if (RBTREE_NODE_COLOR(w->right) == BLACK) {
|
||||||
|
w->left->color = BLACK;
|
||||||
|
w->color = RED;
|
||||||
|
tRBTreeRotateRight(t, w);
|
||||||
|
w = x->parent->right;
|
||||||
|
}
|
||||||
|
w->color = x->parent->color;
|
||||||
|
x->parent->color = BLACK;
|
||||||
|
w->right->color = BLACK;
|
||||||
|
tRBTreeRotateLeft(t, x->parent);
|
||||||
|
x = t->rootNode;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SRBTreeNode *w = x->parent->left;
|
||||||
|
if (RBTREE_NODE_COLOR(w) == RED) {
|
||||||
|
w->color = BLACK;
|
||||||
|
x->parent->color = RED;
|
||||||
|
tRBTreeRotateRight(t, x->parent);
|
||||||
|
w = x->parent->left;
|
||||||
|
}
|
||||||
|
if (RBTREE_NODE_COLOR(w->right) == BLACK && RBTREE_NODE_COLOR(w->left) == BLACK) {
|
||||||
|
w->color = RED;
|
||||||
|
x = x->parent;
|
||||||
|
} else {
|
||||||
|
if (RBTREE_NODE_COLOR(w->left) == BLACK) {
|
||||||
|
w->right->color = BLACK;
|
||||||
|
w->color = RED;
|
||||||
|
tRBTreeRotateLeft(t, w);
|
||||||
|
w = x->parent->left;
|
||||||
|
}
|
||||||
|
w->color = x->parent->color;
|
||||||
|
x->parent->color = BLACK;
|
||||||
|
w->left->color = BLACK;
|
||||||
|
tRBTreeRotateRight(t, x->parent);
|
||||||
|
x = t->rootNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x->color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tRBTreeDrop(SRBTree *t, SRBTreeNode *z) {
|
||||||
|
// update min/max node
|
||||||
|
if (t->minNode == z) {
|
||||||
|
t->minNode = tRBTreeSuccessor(t->minNode);
|
||||||
|
}
|
||||||
|
if (t->maxNode == z) {
|
||||||
|
t->maxNode = tRBTreePredecessor(t->maxNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop impl
|
// drop impl
|
||||||
if (pNode->left == NULL) {
|
SRBTreeNode *y = z;
|
||||||
// transplant right
|
SRBTreeNode *x;
|
||||||
if (pNode->parent == NULL) {
|
ECOLOR oColor = y->color;
|
||||||
pTree->rootNode = pNode->right;
|
|
||||||
} else if (pNode == pNode->parent->left) {
|
|
||||||
pNode->parent->left = pNode->right;
|
|
||||||
} else {
|
|
||||||
pNode->parent->right = pNode->right;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pNode->right) {
|
if (z->left == NULL) {
|
||||||
pNode->right->parent = pNode->parent;
|
x = z->right;
|
||||||
}
|
tRBTreeTransplant(t, z, z->right);
|
||||||
} else if (pNode->right == NULL) {
|
} else if (z->right == NULL) {
|
||||||
// transplant left
|
x = z->left;
|
||||||
if (pNode->parent == NULL) {
|
tRBTreeTransplant(t, z, z->left);
|
||||||
pTree->rootNode = pNode->left;
|
|
||||||
} else if (pNode == pNode->parent->left) {
|
|
||||||
pNode->parent->left = pNode->left;
|
|
||||||
} else {
|
} else {
|
||||||
pNode->parent->right = pNode->left;
|
y = tRBTreeSuccessor(z);
|
||||||
}
|
oColor = y->color;
|
||||||
|
x = y->right;
|
||||||
if (pNode->left) {
|
if (y->parent == z) {
|
||||||
pNode->left->parent = pNode->parent;
|
x->parent = z;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SRBTreeNode *y = tRBTreeSuccessor(pNode);
|
tRBTreeTransplant(t, y, y->right);
|
||||||
pNode->color = RBTREE_NODE_COLOR(y);
|
y->right = z->right;
|
||||||
|
y->right->parent = y;
|
||||||
|
}
|
||||||
|
tRBTreeTransplant(t, z, y);
|
||||||
|
y->left = z->left;
|
||||||
|
y->left->parent = y;
|
||||||
|
y->color = z->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix
|
// fix
|
||||||
if (pNode->color == BLACK) {
|
if (oColor == BLACK) {
|
||||||
// TODO
|
tRBTreeDropFixup(t, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue