mirror of
https://github.com/reactos/reactos.git
synced 2025-06-22 23:20:16 +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)
|
void avl_init(udict_t *ud)
|
||||||
{
|
{
|
||||||
ud->sentinel.left = ud->sentinel.right = ud->sentinel.parent =
|
ud->BalancedRoot.left = ud->BalancedRoot.right =
|
||||||
&ud->sentinel;
|
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)
|
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->right = nil;
|
||||||
node->balance = BALANCED;
|
node->balance = BALANCED;
|
||||||
|
|
||||||
if (Insert(ud, node, &nil->left, nil)) {
|
if (Insert(ud, node, &ud->BalancedRoot.left, nil)) {
|
||||||
nil->balance = LEFTHEAVY;
|
nil->balance = LEFTHEAVY;
|
||||||
}/*if*/
|
}/*if*/
|
||||||
|
|
||||||
|
@ -253,6 +256,7 @@ void avl_delete_node(udict_t *ud, udict_node_t *node)
|
||||||
/* root has been deleted */
|
/* root has been deleted */
|
||||||
if (child == nil) {
|
if (child == nil) {
|
||||||
parent->balance = BALANCED;
|
parent->balance = BALANCED;
|
||||||
|
ud->BalancedRoot.left = nil;
|
||||||
}/*if*/
|
}/*if*/
|
||||||
}/*if*/
|
}/*if*/
|
||||||
|
|
||||||
|
@ -297,10 +301,17 @@ void avl_delete_node(udict_t *ud, udict_node_t *node)
|
||||||
}/*while*/
|
}/*while*/
|
||||||
}/*avl_delete*/
|
}/*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 avl_search(udict_t *ud, void *_key, udict_node_t *here, udict_node_t **where)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
if (avl_is_nil(ud, here))
|
||||||
|
return TableInsertAsLeft;
|
||||||
|
|
||||||
result = ud->compare(ud, _key, key(here));
|
result = ud->compare(ud, _key, key(here));
|
||||||
|
|
||||||
if (result == EQUAL) {
|
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 (result == LESS) {
|
||||||
if( here->left == &ud->sentinel ) {
|
if( here->left == tree_null_priv(ud) ) {
|
||||||
*where = here;
|
*where = here;
|
||||||
return TableInsertAsLeft;
|
return TableInsertAsLeft;
|
||||||
}
|
}
|
||||||
return avl_search(ud, _key, here->left, where);
|
return avl_search(ud, _key, here->left, where);
|
||||||
}/*if*/
|
}/*if*/
|
||||||
else {
|
else {
|
||||||
if( here->right == &ud->sentinel ) {
|
if( here->right == tree_null_priv(ud) ) {
|
||||||
*where = here;
|
*where = here;
|
||||||
return TableInsertAsRight;
|
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)
|
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)
|
udict_node_t *avl_first(udict_t *ud)
|
||||||
|
|
|
@ -47,5 +47,5 @@
|
||||||
#define nodefree FreeRoutine
|
#define nodefree FreeRoutine
|
||||||
#define context TableContext
|
#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) {
|
if (node == delparent->left) {
|
||||||
delparent->left = child;
|
delparent->left = child;
|
||||||
} else {
|
} else {
|
||||||
assert (node == delparent->right);
|
//assert (node == delparent->right);
|
||||||
delparent->right = child;
|
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_left(udict_node_t *, udict_node_t *);
|
||||||
void udict_tree_rotate_right(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_root_priv(T) ((T)->BalancedRoot.left)
|
||||||
#define tree_null_priv(L) (&(L)->sentinel)
|
#define tree_null_priv(L) ((L)->BalancedRoot.parent)
|
||||||
#define TREE_DEPTH_MAX 64
|
#define TREE_DEPTH_MAX 64
|
||||||
|
|
|
@ -56,9 +56,9 @@ typedef enum {
|
||||||
} udict_rb_color_t;
|
} udict_rb_color_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
udict_balanced,
|
udict_balanced = 0,
|
||||||
udict_leftheavy,
|
udict_leftheavy = -1,
|
||||||
udict_rightheavy
|
udict_rightheavy = 1
|
||||||
} udict_avl_balance_t;
|
} udict_avl_balance_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
|
@ -60,7 +60,7 @@ RtlLookupElementGenericTableFullAvl (
|
||||||
PRTL_BALANCED_LINKS OurNodeOrParent;
|
PRTL_BALANCED_LINKS OurNodeOrParent;
|
||||||
TABLE_SEARCH_RESULT OurSearchResult;
|
TABLE_SEARCH_RESULT OurSearchResult;
|
||||||
|
|
||||||
if( Table->NumberGenericTableElements )
|
if( !Table->NumberGenericTableElements )
|
||||||
{
|
{
|
||||||
*SearchResult = TableEmptyTree;
|
*SearchResult = TableEmptyTree;
|
||||||
*NodeOrParent = NULL;
|
*NodeOrParent = NULL;
|
||||||
|
@ -68,7 +68,8 @@ RtlLookupElementGenericTableFullAvl (
|
||||||
}
|
}
|
||||||
|
|
||||||
OurSearchResult = avl_search
|
OurSearchResult = avl_search
|
||||||
(Table, Buffer, &Table->BalancedRoot, &OurNodeOrParent);
|
(Table, Buffer,
|
||||||
|
Table->BalancedRoot.LeftChild, &OurNodeOrParent);
|
||||||
|
|
||||||
if(SearchResult) *SearchResult = OurSearchResult;
|
if(SearchResult) *SearchResult = OurSearchResult;
|
||||||
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
||||||
|
@ -129,7 +130,7 @@ RtlDeleteElementGenericTableAvl (
|
||||||
|
|
||||||
if( Result == TableFoundNode )
|
if( Result == TableFoundNode )
|
||||||
{
|
{
|
||||||
avl_delete_node(Table, Buffer);
|
avl_delete_node(Table, Node);
|
||||||
Table->FreeRoutine(Table, Node);
|
Table->FreeRoutine(Table, Node);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -169,20 +170,17 @@ RtlEnumerateGenericTableAvl (
|
||||||
if( Restart )
|
if( Restart )
|
||||||
{
|
{
|
||||||
Table->RestartKey = avl_first(Table);
|
Table->RestartKey = avl_first(Table);
|
||||||
return avl_data(Table->RestartKey);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Table->RestartKey = avl_next(Table, Table->RestartKey);
|
Table->RestartKey = avl_next(Table, Table->RestartKey);
|
||||||
if( avl_is_nil(Table, Table->RestartKey) )
|
}
|
||||||
|
if( !Table->RestartKey )
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
return avl_data(Table->RestartKey);
|
return avl_data(Table->RestartKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -363,25 +361,19 @@ RtlInsertElementGenericTableFullAvl (
|
||||||
if(NewElement)
|
if(NewElement)
|
||||||
*NewElement = FALSE;
|
*NewElement = FALSE;
|
||||||
|
|
||||||
if( Table->NumberGenericTableElements )
|
|
||||||
{
|
|
||||||
OurSearchResult = TableEmptyTree;
|
|
||||||
OurNodeOrParent = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
OurSearchResult = avl_search
|
OurSearchResult = avl_search
|
||||||
(Table, Buffer, &Table->BalancedRoot, &OurNodeOrParent);
|
(Table, Buffer,
|
||||||
|
Table->BalancedRoot.LeftChild, &OurNodeOrParent);
|
||||||
|
|
||||||
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
if(NodeOrParent) *NodeOrParent = OurNodeOrParent;
|
||||||
if(SearchResult) *SearchResult = OurSearchResult;
|
if(SearchResult) *SearchResult = OurSearchResult;
|
||||||
|
|
||||||
if(OurSearchResult == TableFoundNode)
|
if(OurSearchResult == TableFoundNode)
|
||||||
{
|
{
|
||||||
if(NewElement)
|
RtlDeleteElementGenericTableAvl(Table, Buffer);
|
||||||
*NewElement = TRUE;
|
return RtlInsertElementGenericTableFullAvl
|
||||||
RtlCopyMemory(avl_data(OurNodeOrParent), Buffer, BufferSize);
|
(Table, Buffer, BufferSize,
|
||||||
return avl_data(OurNodeOrParent);
|
NewElement, NodeOrParent, SearchResult);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -392,6 +384,7 @@ RtlInsertElementGenericTableFullAvl (
|
||||||
|
|
||||||
if( !NewNode ) return NULL;
|
if( !NewNode ) return NULL;
|
||||||
|
|
||||||
|
NewNode->Balance = 0;
|
||||||
RtlCopyMemory(avl_data(NewNode), Buffer, BufferSize);
|
RtlCopyMemory(avl_data(NewNode), Buffer, BufferSize);
|
||||||
|
|
||||||
OurNodeOrParent = NewNode;
|
OurNodeOrParent = NewNode;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue