more code

This commit is contained in:
Hongze Cheng 2022-08-25 16:21:13 +08:00
parent c1462d726a
commit ffa5812053
2 changed files with 127 additions and 68 deletions

View File

@ -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;

View File

@ -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);
} }
} }