more code
This commit is contained in:
parent
b8a70bc5b0
commit
c3998092f7
|
@ -38,8 +38,8 @@ SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey);
|
||||||
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
||||||
|
|
||||||
// SRBTreeIter =============================================
|
// SRBTreeIter =============================================
|
||||||
#define tRBTreeIterCreate(tree, descend) \
|
#define tRBTreeIterCreate(tree, ascend) \
|
||||||
(SRBTreeIter) { .des = (descend), .pTree = (tree), .pNode = (descend) ? (tree)->maxNode : (tree)->minNode }
|
(SRBTreeIter) { .asc = (ascend), .pTree = (tree), .pNode = (ascend) ? (tree)->minNode : (tree)->maxNode }
|
||||||
|
|
||||||
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter);
|
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ struct SRBTree {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SRBTreeIter {
|
struct SRBTreeIter {
|
||||||
int8_t des;
|
int8_t asc;
|
||||||
SRBTree *pTree;
|
SRBTree *pTree;
|
||||||
SRBTreeNode *pNode;
|
SRBTreeNode *pNode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,6 +60,55 @@ static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *pNode) {
|
||||||
pNode->parent = left;
|
pNode->parent = left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SRBTreeNode *tRBTreeSuccessor(SRBTreeNode *pNode) {
|
||||||
|
if (pNode->right) {
|
||||||
|
pNode = pNode->right;
|
||||||
|
while (pNode->left) {
|
||||||
|
pNode = pNode->left;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (true) {
|
||||||
|
if (pNode->parent) {
|
||||||
|
if (pNode == pNode->parent->left) {
|
||||||
|
pNode = pNode->parent;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
pNode = pNode->parent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pNode = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRBTreeNode *tRBTreePredecessor(SRBTreeNode *pNode) {
|
||||||
|
if (pNode->left) {
|
||||||
|
pNode = pNode->left;
|
||||||
|
while (pNode->right) {
|
||||||
|
pNode = pNode->right;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (true) {
|
||||||
|
if (pNode->parent) {
|
||||||
|
if (pNode == pNode->parent->right) {
|
||||||
|
pNode = pNode->parent;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
pNode = pNode->parent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pNode = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
|
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
|
||||||
pNew->left = NULL;
|
pNew->left = NULL;
|
||||||
pNew->right = NULL;
|
pNew->right = NULL;
|
||||||
|
@ -153,8 +202,12 @@ SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
|
||||||
|
|
||||||
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode) {
|
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode) {
|
||||||
// update min/max node
|
// update min/max node
|
||||||
if (pTree->minNode == pNode) pTree->minNode = pNode->parent;
|
if (pTree->minNode == pNode) {
|
||||||
if (pTree->maxNode == pNode) pTree->maxNode = pNode->parent;
|
pTree->minNode = tRBTreeSuccessor(pTree->minNode);
|
||||||
|
}
|
||||||
|
if (pTree->maxNode == pNode) {
|
||||||
|
pTree->maxNode = tRBTreePredecessor(pTree->maxNode);
|
||||||
|
}
|
||||||
|
|
||||||
// drop impl
|
// drop impl
|
||||||
if (pNode->left == NULL) {
|
if (pNode->left == NULL) {
|
||||||
|
@ -208,19 +261,7 @@ void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey) {
|
SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey) {
|
||||||
SRBTreeNode *pNode = pTree->rootNode;
|
SRBTreeNode *pNode = tRBTreeGet(pTree, pKey);
|
||||||
|
|
||||||
while (pNode) {
|
|
||||||
int32_t c = pTree->cmprFn(pKey, pNode->payload);
|
|
||||||
|
|
||||||
if (c < 0) {
|
|
||||||
pNode = pNode->left;
|
|
||||||
} else if (c > 0) {
|
|
||||||
pNode = pNode->right;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pNode) {
|
if (pNode) {
|
||||||
tRBTreeDrop(pTree, pNode);
|
tRBTreeDrop(pTree, pNode);
|
||||||
|
@ -250,53 +291,14 @@ SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey) {
|
||||||
// SRBTreeIter ================================================
|
// SRBTreeIter ================================================
|
||||||
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter) {
|
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter) {
|
||||||
SRBTreeNode *pNode = pIter->pNode;
|
SRBTreeNode *pNode = pIter->pNode;
|
||||||
SRBTree *pTree = pIter->pTree;
|
|
||||||
|
|
||||||
if (pIter->pNode) {
|
if (pIter->pNode) {
|
||||||
if (pIter->des) {
|
if (pIter->asc) {
|
||||||
// descend
|
|
||||||
if (pIter->pNode->left) {
|
|
||||||
pIter->pNode = pIter->pNode->left;
|
|
||||||
while (pIter->pNode->right) {
|
|
||||||
pIter->pNode = pIter->pNode->right;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (true) {
|
|
||||||
if (pIter->pNode->parent) {
|
|
||||||
if (pIter->pNode == pIter->pNode->parent->right) {
|
|
||||||
pIter->pNode = pIter->pNode->parent;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
pIter->pNode = pIter->pNode->parent;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pIter->pNode = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ascend
|
// ascend
|
||||||
if (pIter->pNode->right) {
|
pIter->pNode = tRBTreeSuccessor(pIter->pNode);
|
||||||
pIter->pNode = pIter->pNode->right;
|
} else {
|
||||||
while (pIter->pNode->left) {
|
// descend
|
||||||
pIter->pNode = pIter->pNode->left;
|
pIter->pNode = tRBTreePredecessor(pIter->pNode);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (true) {
|
|
||||||
if (pIter->pNode->parent) {
|
|
||||||
if (pIter->pNode == pIter->pNode->parent->left) {
|
|
||||||
pIter->pNode = pIter->pNode->parent;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
pIter->pNode = pIter->pNode->parent;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pIter->pNode = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,13 @@ TEST(trbtreeTest, rbtree_test1) {
|
||||||
tRBTreePut(&rt, pNode);
|
tRBTreePut(&rt, pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRBTreeIter rti = tRBTreeIterCreate(&rt, 0);
|
SRBTreeIter rti = tRBTreeIterCreate(&rt, 1);
|
||||||
SRBTreeNode *pNode = tRBTreeIterNext(&rti);
|
SRBTreeNode *pNode = tRBTreeIterNext(&rti);
|
||||||
int la = 0;
|
int la = 0;
|
||||||
while (pNode) {
|
while (pNode) {
|
||||||
GTEST_ASSERT_GT(*(int *)pNode->payload, la);
|
GTEST_ASSERT_GT(*(int *)pNode->payload, la);
|
||||||
la = *(int *)pNode->payload;
|
la = *(int *)pNode->payload;
|
||||||
|
// printf("%d\n", la);
|
||||||
pNode = tRBTreeIterNext(&rti);
|
pNode = tRBTreeIterNext(&rti);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue