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:
Art Yerkes 2006-10-13 07:02:04 +00:00
parent 20d422c02d
commit a8e91f11af
6 changed files with 39 additions and 35 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,18 +170,15 @@ 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;
} }
/* /*
@ -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;