|
|
@ -54,8 +54,7 @@ |
|
|
#include <unistd.h> |
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
#include "tr/memory.h" |
|
|
#include "tr/memory.h" |
|
|
|
|
|
|
|
|
enum rbColor {rbBlack=1, rbRed=2}; |
|
|
|
|
|
|
|
|
#include "tr/tree_macros.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct memSegment |
|
|
struct memSegment |
|
|
@ -64,7 +63,9 @@ struct memSegment |
|
|
size_t size; |
|
|
size_t size; |
|
|
void * ptr; |
|
|
void * ptr; |
|
|
|
|
|
|
|
|
enum rbColor color; |
|
|
|
|
|
|
|
|
TR_rbColor color; |
|
|
|
|
|
|
|
|
|
|
|
struct memSegment * data; |
|
|
|
|
|
|
|
|
struct memSegment * next; |
|
|
struct memSegment * next; |
|
|
struct memSegment * last; |
|
|
struct memSegment * last; |
|
|
@ -84,6 +85,8 @@ newElement(size_t size) |
|
|
element->size = size; |
|
|
element->size = size; |
|
|
element->ptr = (void*)element + sizeof(struct memSegment); |
|
|
element->ptr = (void*)element + sizeof(struct memSegment); |
|
|
|
|
|
|
|
|
|
|
|
element->data = element; |
|
|
|
|
|
|
|
|
element->next = NULL; |
|
|
element->next = NULL; |
|
|
element->last = NULL; |
|
|
element->last = NULL; |
|
|
|
|
|
|
|
|
@ -121,133 +124,6 @@ findElement(struct memSegment * tree, size_t size) |
|
|
return fitting; |
|
|
return fitting; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* function to get specific elements needed for |
|
|
|
|
|
* rb handling, grandparent, uncle and sibbling |
|
|
|
|
|
*/ |
|
|
|
|
|
static |
|
|
|
|
|
struct memSegment * |
|
|
|
|
|
grandparent(struct memSegment * node) |
|
|
|
|
|
{ |
|
|
|
|
|
if (NULL != node && NULL != node->parent) { |
|
|
|
|
|
return node->parent->parent; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
|
|
|
struct memSegment * |
|
|
|
|
|
uncle(struct memSegment * node) |
|
|
|
|
|
{ |
|
|
|
|
|
struct memSegment * gp = grandparent(node); |
|
|
|
|
|
|
|
|
|
|
|
if (NULL == gp) { |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (node->parent == gp->left) { |
|
|
|
|
|
return gp->right; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return gp->left; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
|
|
|
struct memSegment * |
|
|
|
|
|
sibling(struct memSegment * node) |
|
|
|
|
|
{ |
|
|
|
|
|
if (NULL == node) { |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (NULL == node->parent->left || node == node->parent->left) { |
|
|
|
|
|
return node->parent->right; |
|
|
|
|
|
} else { |
|
|
|
|
|
return node->parent->left; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* tree modifications...needed for rb handling. |
|
|
|
|
|
*/ |
|
|
|
|
|
static |
|
|
|
|
|
void |
|
|
|
|
|
rotateLeft(struct memSegment ** tree, struct memSegment * node) |
|
|
|
|
|
{ |
|
|
|
|
|
struct memSegment * rightChild = node->right; |
|
|
|
|
|
struct memSegment * rcLeftSub = node->right->left; |
|
|
|
|
|
|
|
|
|
|
|
rightChild->left = node; |
|
|
|
|
|
rightChild->parent = node->parent; |
|
|
|
|
|
node->right = rcLeftSub; |
|
|
|
|
|
if (NULL != rcLeftSub) { |
|
|
|
|
|
rcLeftSub->parent = node; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (node->parent) { |
|
|
|
|
|
if (node->parent->left == node) { |
|
|
|
|
|
node->parent->left = rightChild; |
|
|
|
|
|
} else { |
|
|
|
|
|
node->parent->right = rightChild; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
*tree = rightChild; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
node->parent = rightChild; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
|
|
|
void |
|
|
|
|
|
rotateRight(struct memSegment ** tree, struct memSegment * node) |
|
|
|
|
|
{ |
|
|
|
|
|
struct memSegment * leftChild = node->left; |
|
|
|
|
|
struct memSegment * lcRightSub = node->left->right; |
|
|
|
|
|
|
|
|
|
|
|
leftChild->right = node; |
|
|
|
|
|
leftChild->parent = node->parent; |
|
|
|
|
|
node->left = lcRightSub; |
|
|
|
|
|
if (NULL != lcRightSub) { |
|
|
|
|
|
lcRightSub->parent = node; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (node->parent) { |
|
|
|
|
|
if (node->parent->left == node) { |
|
|
|
|
|
node->parent->left = leftChild; |
|
|
|
|
|
} else { |
|
|
|
|
|
node->parent->right = leftChild; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
*tree = leftChild; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
node->parent = leftChild; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
|
|
|
void |
|
|
|
|
|
replaceNode( |
|
|
|
|
|
struct memSegment ** tree, |
|
|
|
|
|
struct memSegment * node1, |
|
|
|
|
|
struct memSegment * node2) |
|
|
|
|
|
{ |
|
|
|
|
|
if (NULL != node1->parent) { |
|
|
|
|
|
if (node1 == node1->parent->left) { |
|
|
|
|
|
node1->parent->left = node2; |
|
|
|
|
|
} else { |
|
|
|
|
|
node1->parent->right = node2; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
*tree = node2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (NULL != node2) { |
|
|
|
|
|
node2->parent = node1->parent; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* insert element in tree |
|
|
* insert element in tree |
|
|
*/ |
|
|
*/ |
|
|
@ -324,8 +200,8 @@ insertElement(struct memSegment ** tree, struct memSegment * element) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// case 3 |
|
|
// case 3 |
|
|
u = uncle(node); |
|
|
|
|
|
g = grandparent(node); |
|
|
|
|
|
|
|
|
u = TR_TREE_UNCLE(node); |
|
|
|
|
|
g = TR_TREE_GRANDPARENT(node); |
|
|
|
|
|
|
|
|
if (u != NULL && u->color == rbRed) { |
|
|
if (u != NULL && u->color == rbRed) { |
|
|
node->parent->color = rbBlack; |
|
|
node->parent->color = rbBlack; |
|
|
@ -338,24 +214,24 @@ insertElement(struct memSegment ** tree, struct memSegment * element) |
|
|
|
|
|
|
|
|
// case 4 |
|
|
// case 4 |
|
|
if (node == node->parent->right && node->parent == g->left) { |
|
|
if (node == node->parent->right && node->parent == g->left) { |
|
|
rotateLeft(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, tree, node->parent); |
|
|
node = node->left; |
|
|
node = node->left; |
|
|
} else if (node == node->parent->left && node->parent == g->right) { |
|
|
} else if (node == node->parent->left && node->parent == g->right) { |
|
|
|
|
|
|
|
|
rotateRight(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, tree, node->parent); |
|
|
node = node->right; |
|
|
node = node->right; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// case 5 |
|
|
// case 5 |
|
|
g = grandparent(node); |
|
|
|
|
|
|
|
|
g = TR_TREE_GRANDPARENT(node); |
|
|
|
|
|
|
|
|
node->parent->color = rbBlack; |
|
|
node->parent->color = rbBlack; |
|
|
g->color = rbRed; |
|
|
g->color = rbRed; |
|
|
|
|
|
|
|
|
if (node == node->parent->left) { |
|
|
if (node == node->parent->left) { |
|
|
rotateRight(tree, g); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, tree, g); |
|
|
} else { |
|
|
} else { |
|
|
rotateLeft(tree, g); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, tree, g); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// we're done.. |
|
|
// we're done.. |
|
|
@ -366,36 +242,6 @@ insertElement(struct memSegment ** tree, struct memSegment * element) |
|
|
return new_node; |
|
|
return new_node; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* delete element from tree |
|
|
|
|
|
* here multiple functions are involved.... |
|
|
|
|
|
* ======================================================================= |
|
|
|
|
|
*/ |
|
|
|
|
|
/** |
|
|
|
|
|
* find minimum of the right subtree aka leftmost leaf of right subtree |
|
|
|
|
|
* aka left in-order successor. |
|
|
|
|
|
* We return the parent of the element in the out argument parent. |
|
|
|
|
|
* This can be NULL wenn calling. |
|
|
|
|
|
* |
|
|
|
|
|
* 2: *successor = {size = 80, ptr = 0x603ae0, color = rbRed, parent = 0x603160, |
|
|
|
|
|
* left = 0x0, right = 0x0} |
|
|
|
|
|
* 1: *node = {size = 70, ptr = 0x603a60, color = rbBlack, parent = 0x603070, |
|
|
|
|
|
* left = 0x6030e0, right = 0x6031e0} |
|
|
|
|
|
* |
|
|
|
|
|
*/ |
|
|
|
|
|
static |
|
|
|
|
|
struct memSegment * |
|
|
|
|
|
findInOrderSuccessor(struct memSegment * tree) |
|
|
|
|
|
{ |
|
|
|
|
|
struct memSegment * node = tree->right; |
|
|
|
|
|
|
|
|
|
|
|
while (NULL != node->left) { |
|
|
|
|
|
node = node->left; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return node; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
static |
|
|
struct memSegment * |
|
|
struct memSegment * |
|
|
deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
@ -456,14 +302,19 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
|
|
|
|
|
|
// case 1: two children |
|
|
// case 1: two children |
|
|
if (NULL != node->left && NULL != node->right) { |
|
|
if (NULL != node->left && NULL != node->right) { |
|
|
struct memSegment * successor = findInOrderSuccessor(node); |
|
|
|
|
|
|
|
|
struct memSegment * successor; |
|
|
|
|
|
struct memSegment * tmpparent; |
|
|
|
|
|
struct memSegment * tmpleft; |
|
|
|
|
|
struct memSegment * tmpright; |
|
|
|
|
|
TR_rbColor tmpcolor; |
|
|
|
|
|
|
|
|
enum rbColor tmpcolor = successor->color; |
|
|
|
|
|
struct memSegment * tmpparent = successor->parent; |
|
|
|
|
|
struct memSegment * tmpleft = successor->left; |
|
|
|
|
|
struct memSegment * tmpright = successor->right; |
|
|
|
|
|
|
|
|
TR_TREE_INORDER_SUCC(node, successor); |
|
|
|
|
|
tmpparent = successor->parent; |
|
|
|
|
|
tmpleft = successor->left; |
|
|
|
|
|
tmpright = successor->right; |
|
|
|
|
|
tmpcolor = successor->color; |
|
|
|
|
|
|
|
|
replaceNode(tree, node, successor); |
|
|
|
|
|
|
|
|
TR_TREE_REPLACE_NODE(tree, node, successor); |
|
|
|
|
|
|
|
|
successor->color = node->color; |
|
|
successor->color = node->color; |
|
|
successor->left = node->left; |
|
|
successor->left = node->left; |
|
|
@ -486,7 +337,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
|
|
|
|
|
|
// Precondition: n has at most one non-null child. |
|
|
// Precondition: n has at most one non-null child. |
|
|
child = (NULL == node->right) ? node->left : node->right; |
|
|
child = (NULL == node->right) ? node->left : node->right; |
|
|
replaceNode(tree, node, child); |
|
|
|
|
|
|
|
|
TR_TREE_REPLACE_NODE(tree, node, child); |
|
|
|
|
|
|
|
|
// delete one child case |
|
|
// delete one child case |
|
|
// TODO this is overly complex as simply derived from the function... |
|
|
// TODO this is overly complex as simply derived from the function... |
|
|
@ -518,7 +369,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// case 2 |
|
|
// case 2 |
|
|
s = sibling(node); |
|
|
|
|
|
|
|
|
s = TR_TREE_SIBLING(node); |
|
|
|
|
|
|
|
|
if (NULL != s && s->color == rbRed) { |
|
|
if (NULL != s && s->color == rbRed) { |
|
|
node->parent->color = rbRed; |
|
|
node->parent->color = rbRed; |
|
|
@ -530,13 +381,13 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
* null we must be left, even if its set to NULL previously |
|
|
* null we must be left, even if its set to NULL previously |
|
|
*/ |
|
|
*/ |
|
|
if (NULL != node->parent->right && node != node->parent->right) { |
|
|
if (NULL != node->parent->right && node != node->parent->right) { |
|
|
rotateLeft(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, tree, node->parent); |
|
|
} else { |
|
|
} else { |
|
|
rotateRight(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, tree, node->parent); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
s = sibling(node); |
|
|
|
|
|
|
|
|
s = TR_TREE_SIBLING(node); |
|
|
// case 3 / 4 |
|
|
// case 3 / 4 |
|
|
if (NULL == s || ((s->color == rbBlack) && |
|
|
if (NULL == s || ((s->color == rbBlack) && |
|
|
(NULL == s->left || s->left->color == rbBlack) && |
|
|
(NULL == s->left || s->left->color == rbBlack) && |
|
|
@ -577,7 +428,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
s->color = rbRed; |
|
|
s->color = rbRed; |
|
|
s->left->color = rbBlack; |
|
|
s->left->color = rbBlack; |
|
|
|
|
|
|
|
|
rotateRight(tree, s); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, tree, s); |
|
|
} else if ((node == node->parent->right) && |
|
|
} else if ((node == node->parent->right) && |
|
|
(NULL == s->left || s->left->color == rbBlack) && |
|
|
(NULL == s->left || s->left->color == rbBlack) && |
|
|
(NULL != s->right && s->right->color == rbRed)) { |
|
|
(NULL != s->right && s->right->color == rbRed)) { |
|
|
@ -585,11 +436,11 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
s->color = rbRed; |
|
|
s->color = rbRed; |
|
|
s->right->color = rbBlack; |
|
|
s->right->color = rbBlack; |
|
|
|
|
|
|
|
|
rotateLeft(tree, s); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, tree, s); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
s = sibling(node); |
|
|
|
|
|
|
|
|
s = TR_TREE_SIBLING(node); |
|
|
// case 6 |
|
|
// case 6 |
|
|
if (NULL != s) { |
|
|
if (NULL != s) { |
|
|
s->color = node->parent->color; |
|
|
s->color = node->parent->color; |
|
|
@ -607,12 +458,12 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
if (NULL != s->right) { |
|
|
if (NULL != s->right) { |
|
|
s->right->color = rbBlack; |
|
|
s->right->color = rbBlack; |
|
|
} |
|
|
} |
|
|
rotateLeft(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, tree, node->parent); |
|
|
} else { |
|
|
} else { |
|
|
if (NULL != s->left) { |
|
|
if (NULL != s->left) { |
|
|
s->left->color = rbBlack; |
|
|
s->left->color = rbBlack; |
|
|
} |
|
|
} |
|
|
rotateRight(tree, node->parent); |
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, tree, node->parent); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|