mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
Fixen. Delete is still broken.
We now use BalancedRoot->Parent as the nil element and distinguish it from the embedded element. Fix null and root macros, assert macro and some other stuff. svn path=/trunk/; revision=24495
This commit is contained in:
parent
20d422c02d
commit
a8e91f11af
6 changed files with 39 additions and 35 deletions
|
@ -36,8 +36,11 @@
|
|||
|
||||
void avl_init(udict_t *ud)
|
||||
{
|
||||
ud->sentinel.left = ud->sentinel.right = ud->sentinel.parent =
|
||||
&ud->sentinel;
|
||||
ud->BalancedRoot.left = ud->BalancedRoot.right =
|
||||
ud->BalancedRoot.parent = (udict_node_t*)
|
||||
ud->AllocateRoutine(ud, sizeof(udict_node_t));
|
||||
ud->BalancedRoot.parent->left = ud->BalancedRoot.parent->right =
|
||||
ud->BalancedRoot.parent->parent = ud->BalancedRoot.parent;
|
||||
}
|
||||
|
||||
void RotateLeft(udict_node_t **top)
|
||||
|
@ -197,7 +200,7 @@ void avl_insert_node(udict_t *ud, udict_node_t *node)
|
|||
node->right = nil;
|
||||
node->balance = BALANCED;
|
||||
|
||||
if (Insert(ud, node, &nil->left, nil)) {
|
||||
if (Insert(ud, node, &ud->BalancedRoot.left, nil)) {
|
||||
nil->balance = LEFTHEAVY;
|
||||
}/*if*/
|
||||
|
||||
|
@ -253,6 +256,7 @@ void avl_delete_node(udict_t *ud, udict_node_t *node)
|
|||
/* root has been deleted */
|
||||
if (child == nil) {
|
||||
parent->balance = BALANCED;
|
||||
ud->BalancedRoot.left = nil;
|
||||
}/*if*/
|
||||
}/*if*/
|
||||
|
||||
|
@ -297,10 +301,17 @@ void avl_delete_node(udict_t *ud, udict_node_t *node)
|
|||
}/*while*/
|
||||
}/*avl_delete*/
|
||||
|
||||
void *avl_get_data(udict_node_t *here) {
|
||||
return data(here);
|
||||
}
|
||||
|
||||
int avl_search(udict_t *ud, void *_key, udict_node_t *here, udict_node_t **where)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (avl_is_nil(ud, here))
|
||||
return TableInsertAsLeft;
|
||||
|
||||
result = ud->compare(ud, _key, key(here));
|
||||
|
||||
if (result == EQUAL) {
|
||||
|
@ -309,14 +320,14 @@ int avl_search(udict_t *ud, void *_key, udict_node_t *here, udict_node_t **where
|
|||
}
|
||||
|
||||
if (result == LESS) {
|
||||
if( here->left == &ud->sentinel ) {
|
||||
if( here->left == tree_null_priv(ud) ) {
|
||||
*where = here;
|
||||
return TableInsertAsLeft;
|
||||
}
|
||||
return avl_search(ud, _key, here->left, where);
|
||||
}/*if*/
|
||||
else {
|
||||
if( here->right == &ud->sentinel ) {
|
||||
if( here->right == tree_null_priv(ud) ) {
|
||||
*where = here;
|
||||
return TableInsertAsRight;
|
||||
}
|
||||
|
@ -326,7 +337,7 @@ int avl_search(udict_t *ud, void *_key, udict_node_t *here, udict_node_t **where
|
|||
|
||||
int avl_is_nil(udict_t *ud, udict_node_t *node)
|
||||
{
|
||||
return &ud->sentinel == node;
|
||||
return tree_null_priv(ud) == node;
|
||||
}
|
||||
|
||||
udict_node_t *avl_first(udict_t *ud)
|
||||
|
|
|
@ -47,5 +47,5 @@
|
|||
#define nodefree FreeRoutine
|
||||
#define context TableContext
|
||||
|
||||
#define assert(x) { if(x) { RtlAssert(#x, __FILE__, __LINE__, NULL); } }
|
||||
#define assert(x) { if(!(x)) { RtlAssert(#x, __FILE__, __LINE__, NULL); } }
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ void udict_tree_delete(udict_t *ud, udict_node_t *node, udict_node_t **pswap, ud
|
|||
if (node == delparent->left) {
|
||||
delparent->left = child;
|
||||
} else {
|
||||
assert (node == delparent->right);
|
||||
//assert (node == delparent->right);
|
||||
delparent->right = child;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,6 @@ void udict_tree_convert_from_list(udict_t *);
|
|||
void udict_tree_rotate_left(udict_node_t *, udict_node_t *);
|
||||
void udict_tree_rotate_right(udict_node_t *, udict_node_t *);
|
||||
|
||||
#define tree_root_priv(T) ((T)->sentinel.left)
|
||||
#define tree_null_priv(L) (&(L)->sentinel)
|
||||
#define tree_root_priv(T) ((T)->BalancedRoot.left)
|
||||
#define tree_null_priv(L) ((L)->BalancedRoot.parent)
|
||||
#define TREE_DEPTH_MAX 64
|
||||
|
|
|
@ -56,9 +56,9 @@ typedef enum {
|
|||
} udict_rb_color_t;
|
||||
|
||||
typedef enum {
|
||||
udict_balanced,
|
||||
udict_leftheavy,
|
||||
udict_rightheavy
|
||||
udict_balanced = 0,
|
||||
udict_leftheavy = -1,
|
||||
udict_rightheavy = 1
|
||||
} udict_avl_balance_t;
|
||||
|
||||
typedef union {
|
||||
|
|
|
@ -60,7 +60,7 @@ RtlLookupElementGenericTableFullAvl (
|
|||
PRTL_BALANCED_LINKS OurNodeOrParent;
|
||||
TABLE_SEARCH_RESULT OurSearchResult;
|
||||
|
||||
if( Table->NumberGenericTableElements )
|
||||
if( !Table->NumberGenericTableElements )
|
||||
{
|
||||
*SearchResult = TableEmptyTree;
|
||||
*NodeOrParent = NULL;
|
||||
|
@ -68,7 +68,8 @@ RtlLookupElementGenericTableFullAvl (
|
|||
}
|
||||
|
||||
OurSearchResult = avl_search
|
||||
(Table, Buffer, &Table->BalancedRoot, &OurNodeOrParent);
|
||||
(Table, Buffer,
|
||||
Table->BalancedRoot.LeftChild, &OurNodeOrParent);
|
||||
|
||||
if(SearchResult) *SearchResult = OurSearchResult;
|
||||
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
||||
|
@ -129,7 +130,7 @@ RtlDeleteElementGenericTableAvl (
|
|||
|
||||
if( Result == TableFoundNode )
|
||||
{
|
||||
avl_delete_node(Table, Buffer);
|
||||
avl_delete_node(Table, Node);
|
||||
Table->FreeRoutine(Table, Node);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -169,18 +170,15 @@ RtlEnumerateGenericTableAvl (
|
|||
if( Restart )
|
||||
{
|
||||
Table->RestartKey = avl_first(Table);
|
||||
return avl_data(Table->RestartKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
Table->RestartKey = avl_next(Table, Table->RestartKey);
|
||||
if( avl_is_nil(Table, Table->RestartKey) )
|
||||
return NULL;
|
||||
else
|
||||
return avl_data(Table->RestartKey);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if( !Table->RestartKey )
|
||||
return NULL;
|
||||
else
|
||||
return avl_data(Table->RestartKey);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -363,25 +361,19 @@ RtlInsertElementGenericTableFullAvl (
|
|||
if(NewElement)
|
||||
*NewElement = FALSE;
|
||||
|
||||
if( Table->NumberGenericTableElements )
|
||||
{
|
||||
OurSearchResult = TableEmptyTree;
|
||||
OurNodeOrParent = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OurSearchResult = avl_search
|
||||
(Table, Buffer, &Table->BalancedRoot, &OurNodeOrParent);
|
||||
(Table, Buffer,
|
||||
Table->BalancedRoot.LeftChild, &OurNodeOrParent);
|
||||
|
||||
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
||||
if(SearchResult) *SearchResult = OurSearchResult;
|
||||
|
||||
if(OurSearchResult == TableFoundNode)
|
||||
{
|
||||
if(NewElement)
|
||||
*NewElement = TRUE;
|
||||
RtlCopyMemory(avl_data(OurNodeOrParent), Buffer, BufferSize);
|
||||
return avl_data(OurNodeOrParent);
|
||||
RtlDeleteElementGenericTableAvl(Table, Buffer);
|
||||
return RtlInsertElementGenericTableFullAvl
|
||||
(Table, Buffer, BufferSize,
|
||||
NewElement, NodeOrParent, SearchResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -392,6 +384,7 @@ RtlInsertElementGenericTableFullAvl (
|
|||
|
||||
if( !NewNode ) return NULL;
|
||||
|
||||
NewNode->Balance = 0;
|
||||
RtlCopyMemory(avl_data(NewNode), Buffer, BufferSize);
|
||||
|
||||
OurNodeOrParent = NewNode;
|
||||
|
|
Loading…
Reference in a new issue