@ -1,5 +1,5 @@
/*
* Copyright 1995 - 2014 Andrew Smith
* Copyright 1995 - 2015 Andrew Smith
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
@ -23,42 +23,56 @@ static const int dbg = 0;
# define Yo true
# define No false
static K_TRE E nil [ 1 ] = { { Yo , RED_BLACK , NULL , NULL , NULL , NULL , 0 } } ;
static K_NOD E nil [ 1 ] = { { Yo , RED_BLACK , NULL , NULL , NULL , NULL , 0 } } ;
K_TREE * _new_ktre e( KTREE_FFL_ARGS )
static K_NODE * _new_knod e( KTREE_FFL_ARGS )
{
K_TREE * ktree = ( K_TRE E * ) malloc ( sizeof ( * ktre e) ) ;
K_NODE * node = ( K_NOD E * ) malloc ( sizeof ( * nod e) ) ;
if ( ktree = = NULL )
FAIL ( " %s " , " OOM " ) ;
if ( node = = NULL )
FAIL ( " %s " , " node OOM " ) ;
node - > isNil = Yo ;
node - > red = RED_BLACK ;
node - > parent = nil ;
node - > left = nil ;
node - > right = nil ;
node - > data = NULL ;
node - > test = 0 ;
return node ;
}
K_TREE * _new_ktree ( cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , KTREE_FFL_ARGS )
{
K_TREE * tree = ( K_TREE * ) malloc ( sizeof ( * tree ) ) ;
if ( tree = = NULL )
FAIL ( " %s " , " tree OOM " ) ;
tree - > root = _new_knode ( KTREE_FFL_PASS ) ;
ktree - > isNil = Yo ;
ktree - > red = RED_BLACK ;
ktree - > parent = nil ;
ktree - > left = nil ;
ktree - > right = nil ;
ktree - > data = NULL ;
ktree - > test = 0 ;
tree - > cmp_funct = cmp_funct ;
return ktree ;
return tree ;
}
static K_TREE * new_data ( K_ITEM * data , KTREE_FFL_ARGS )
static K_NODE * new_data ( K_ITEM * data , KTREE_FFL_ARGS )
{
K_TREE * ktree = ( K_TREE * ) malloc ( sizeof ( * ktree ) ) ;
K_NODE * knode = ( K_NOD E * ) malloc ( sizeof ( * knod e ) ) ;
if ( ktree = = NULL )
if ( knod e = = NULL )
FAIL ( " %s " , " OOM " ) ;
ktree - > isNil = No ;
ktre e - > red = RED_RED ;
ktre e - > parent = nil ;
ktre e - > left = nil ;
ktre e - > right = nil ;
ktre e - > data = data ;
ktre e - > test = 0 ;
knod e - > isNil = No ;
knod e - > red = RED_RED ;
knod e - > parent = nil ;
knod e - > left = nil ;
knod e - > right = nil ;
knod e - > data = data ;
knod e - > test = 0 ;
return ktre e ;
return knod e ;
}
static int bCount = 0 ;
@ -73,54 +87,54 @@ static long getTestValue()
return + + testValue ;
}
static void show_ktree ( K_TREE * root , char * path , int pos , char * ( * dsp_funct ) ( K_ITEM * ) )
static void show_ktree ( K_NODE * node , char * path , int pos , char * ( * dsp_funct ) ( K_ITEM * ) )
{
char col ;
if ( root - > isNil = = Yo )
if ( node - > isNil = = Yo )
return ;
if ( root - > left - > isNil = = No )
if ( node - > left - > isNil = = No )
{
path [ pos ] = ' L ' ;
path [ pos + 1 ] = ' \0 ' ;
show_ktree ( root - > left , path , pos + 1 , dsp_funct ) ;
show_ktree ( node - > left , path , pos + 1 , dsp_funct ) ;
}
path [ pos ] = ' \0 ' ;
if ( root - > red = = RED_RED )
if ( node - > red = = RED_RED )
col = ' R ' ;
else
// if (root ->red == RED_BLACK)
// if (node ->red == RED_BLACK)
col = ' B ' ;
printf ( " %c %s=%s \n " , col , path , dsp_funct ( root - > data ) ) ;
printf ( " %c %s=%s \n " , col , path , dsp_funct ( node - > data ) ) ;
if ( root - > right - > isNil = = No )
if ( node - > right - > isNil = = No )
{
path [ pos ] = ' R ' ;
path [ pos + 1 ] = ' \0 ' ;
show_ktree ( root - > right , path , pos + 1 , dsp_funct ) ;
show_ktree ( node - > right , path , pos + 1 , dsp_funct ) ;
}
}
void _dump_ktree ( K_TREE * roo t, char * ( * dsp_funct ) ( K_ITEM * ) , KTREE_FFL_ARGS )
void _dump_ktree ( K_TREE * tree , char * ( * dsp_funct ) ( K_ITEM * ) , KTREE_FFL_ARGS )
{
char buf [ 42424 ] ;
printf ( " dump: \n " ) ;
if ( root - > isNil = = No )
if ( tree - > root - > isNil = = No )
{
buf [ 0 ] = ' T ' ;
buf [ 1 ] = ' \0 ' ;
show_ktree ( root , buf , 1 , dsp_funct ) ;
show_ktree ( tree - > root , buf , 1 , dsp_funct ) ;
}
else
printf ( " Empty k tree \n " ) ;
printf ( " Empty tree \n " ) ;
}
void _dsp_ktree ( K_LIST * list , K_TREE * roo t, char * filename , char * msg , KTREE_FFL_ARGS )
void _dsp_ktree ( K_LIST * list , K_TREE * tree , char * filename , char * msg , KTREE_FFL_ARGS )
{
K_TREE_CTX ctx [ 1 ] ;
K_ITEM * item ;
@ -154,11 +168,11 @@ void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL
if ( msg )
fprintf ( stream , " %s %s \n " , stamp , msg ) ;
else
fprintf ( stream , " %s Dump of k tree '%s': \n " , stamp , list - > name ) ;
fprintf ( stream , " %s Dump of tree '%s': \n " , stamp , list - > name ) ;
if ( root - > isNil = = No )
if ( tree - > root - > isNil = = No )
{
item = first_in_ktree ( roo t, ctx ) ;
item = first_in_ktree ( tree , ctx ) ;
while ( item )
{
list - > dsp_func ( item , stream ) ;
@ -172,7 +186,7 @@ void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL
fclose ( stream ) ;
}
static int nilTest ( K_TRE E * node , char * msg , int depth , int count , K_TRE E * nil2 , KTREE_FFL_ARGS )
static int nilTest ( K_NOD E * node , char * msg , int depth , int count , K_NOD E * nil2 , KTREE_FFL_ARGS )
{
if ( node - > isNil = = Yo | | node = = nil2 )
{
@ -231,7 +245,7 @@ static int nilTest(K_TREE *node, char *msg, int depth, int count, K_TREE *nil2,
return ( count ) ;
}
static void bTest ( K_TREE * root , K_TRE E * cur , char * msg , int count , KTREE_FFL_ARGS )
static void bTest ( K_NOD E * cur , char * msg , int count , KTREE_FFL_ARGS )
{
if ( cur - > red ! = RED_RED )
count + + ;
@ -259,108 +273,118 @@ static void bTest(K_TREE *root, K_TREE *cur, char *msg, int count, KTREE_FFL_ARG
else
FAIL ( " BTESTVALUE '%s' count=%d " , msg , count ) ;
bTest ( root , cur - > left , msg , count , KTREE_FFL_PASS ) ;
bTest ( root , cur - > right , msg , count , KTREE_FFL_PASS ) ;
bTest ( cur - > left , msg , count , KTREE_FFL_PASS ) ;
bTest ( cur - > right , msg , count , KTREE_FFL_PASS ) ;
}
}
static void bTestInit ( K_TREE * roo t, char * msg , KTREE_FFL_ARGS )
static void bTestInit ( K_TREE * tree , char * msg , KTREE_FFL_ARGS )
{
bCount = 0 ;
bTestValue = getTestValue ( ) ;
bTest ( root , root , msg , 0 , KTREE_FFL_PASS ) ;
bTest ( tree - > root , msg , 0 , KTREE_FFL_PASS ) ;
}
static void lrpTest ( K_TREE * top , char * msg , KTREE_FFL_ARGS )
static void lrpTest ( K_NODE * node , char * msg , KTREE_FFL_ARGS )
{
if ( top - > test ! = lrpTestValue )
top - > test = lrpTestValue ;
if ( node - > test ! = lrpTestValue )
node - > test = lrpTestValue ;
else
FAIL ( " LRPTESTVALUE '%s' " , msg ) ;
if ( top - > left - > isNil = = No )
if ( node - > left - > isNil = = No )
{
if ( top - > left - > parent ! = top )
if ( node - > left - > parent ! = node )
FAIL ( " LRPTESTL '%s' " , msg ) ;
lrpTest ( top - > left , msg , KTREE_FFL_PASS ) ;
lrpTest ( node - > left , msg , KTREE_FFL_PASS ) ;
}
if ( top - > right - > isNil = = No )
if ( node - > right - > isNil = = No )
{
if ( top - > right - > parent ! = top )
if ( node - > right - > parent ! = node )
FAIL ( " LRPTESTR '%s' " , msg ) ;
lrpTest ( top - > right , msg , KTREE_FFL_PASS ) ;
lrpTest ( node - > right , msg , KTREE_FFL_PASS ) ;
}
}
static __maybe_unused void check_ktree ( K_TREE * roo t, char * msg , K_TRE E * nil2 , int debugNil , int debugLRP , int debugColor , KTREE_FFL_ARGS )
static __maybe_unused void check_ktree ( K_TREE * tree , char * msg , K_NOD E * nil2 , int debugNil , int debugLRP , int debugColor , KTREE_FFL_ARGS )
{
if ( root - > isNil = = Yo )
if ( tree - > root - > isNil = = Yo )
return ;
if ( debugNil )
{
nilTestValue = getTestValue ( ) ;
nilTest ( root , msg , 1 , 0 , nil2 , KTREE_FFL_PASS ) ;
nilTest ( tree - > root , msg , 1 , 0 , nil2 , KTREE_FFL_PASS ) ;
}
if ( debugLRP & & root - > isNil = = No )
if ( debugLRP & & tree - > root - > isNil = = No )
{
lrpTestValue = getTestValue ( ) ;
lrpTest ( root , msg , KTREE_FFL_PASS ) ;
lrpTest ( tree - > root , msg , KTREE_FFL_PASS ) ;
}
if ( debugColor & & root - > isNil = = No )
bTestInit ( roo t, msg , KTREE_FFL_PASS ) ;
if ( debugColor & & tree - > root - > isNil = = No )
bTestInit ( tree , msg , KTREE_FFL_PASS ) ;
}
K_ITEM * _first_in_ktree ( K_TREE * root , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
static K_ITEM * _first_in_knode ( K_NODE * node , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
if ( root - > isNil = = No )
if ( node - > isNil = = No )
{
while ( root - > left - > isNil = = No )
root = root - > left ;
while ( node - > left - > isNil = = No )
node = node - > left ;
* ctx = root ;
return ( root - > data ) ;
* ctx = node ;
return ( node - > data ) ;
}
* ctx = NULL ;
return ( NULL ) ;
}
K_ITEM * _la st_in_ktree ( K_TREE * roo t, K_TREE_CTX * ctx , KTREE_FFL_ARGS )
K_ITEM * _fir st_in_ktree ( K_TREE * tree , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
if ( root - > isNil = = No )
return _first_in_knode ( tree - > root , ctx , KTREE_FFL_PASS ) ;
}
static K_ITEM * _last_in_knode ( K_NODE * node , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
if ( node - > isNil = = No )
{
while ( root - > right - > isNil = = No )
root = root - > right ;
while ( node - > right - > isNil = = No )
node = node - > right ;
* ctx = root ;
return ( root - > data ) ;
* ctx = node ;
return ( node - > data ) ;
}
* ctx = NULL ;
return ( NULL ) ;
}
K_ITEM * _last_in_ktree ( K_TREE * tree , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
return _last_in_knode ( tree - > root , ctx , KTREE_FFL_PASS ) ;
}
K_ITEM * _next_in_ktree ( K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_TREE * parent ;
K_TREE * ktree = ( K_TREE * ) ( * ctx ) ;
K_NOD E * parent ;
K_NODE * knode = ( K_NOD E * ) ( * ctx ) ;
if ( ktre e - > isNil = = No )
if ( knod e - > isNil = = No )
{
if ( ktre e - > right - > isNil = = No )
return ( first_in_ktree ( ktre e- > right , ctx ) ) ;
if ( knod e - > right - > isNil = = No )
return ( _first_in_knode ( knod e- > right , ctx , KTREE_FFL_PASS ) ) ;
else
{
parent = ktre e - > parent ;
while ( parent - > isNil = = No & & ktre e = = parent - > right )
parent = knod e - > parent ;
while ( parent - > isNil = = No & & knod e = = parent - > right )
{
ktre e = parent ;
knod e = parent ;
parent = parent - > parent ;
}
if ( parent - > isNil = = No )
@ -377,19 +401,19 @@ K_ITEM *_next_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS)
K_ITEM * _prev_in_ktree ( K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_TRE E * parent ;
K_TREE * ktree = ( K_TRE E * ) ( * ctx ) ;
K_NOD E * parent ;
K_NODE * knode = ( K_NOD E * ) ( * ctx ) ;
if ( ktre e - > isNil = = No )
if ( knod e - > isNil = = No )
{
if ( ktre e - > left - > isNil = = No )
return ( last_in_ktree ( ktre e- > left , ctx ) ) ;
if ( knod e - > left - > isNil = = No )
return ( _last_in_knode ( knod e- > left , ctx , KTREE_FFL_PASS ) ) ;
else
{
parent = ktre e - > parent ;
while ( parent - > isNil = = No & & ktre e = = parent - > left )
parent = knod e - > parent ;
while ( parent - > isNil = = No & & knod e = = parent - > left )
{
ktre e = parent ;
knod e = parent ;
parent = parent - > parent ;
}
if ( parent - > isNil = = No )
@ -404,9 +428,9 @@ K_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS)
return ( NULL ) ;
}
static K_TRE E * left_rotate ( K_TRE E * root , K_TRE E * about )
static K_NOD E * left_rotate ( K_NOD E * root , K_NOD E * about )
{
K_TRE E * rotate ;
K_NOD E * rotate ;
rotate = about - > right ;
about - > right = rotate - > left ;
@ -432,9 +456,9 @@ static K_TREE *left_rotate(K_TREE *root, K_TREE *about)
return ( root ) ;
}
static K_TRE E * right_rotate ( K_TRE E * root , K_TRE E * about )
static K_NOD E * right_rotate ( K_NOD E * root , K_NOD E * about )
{
K_TRE E * rotate ;
K_NOD E * rotate ;
rotate = about - > left ;
about - > left = rotate - > right ;
@ -458,50 +482,50 @@ static K_TREE *right_rotate(K_TREE *root, K_TREE *about)
return ( root ) ;
}
K_TREE * _add_to_ktree ( K_TREE * roo t, K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , KTREE_FFL_ARGS )
void _add_to_ktree ( K_TREE * tree , K_ITEM * data , KTREE_FFL_ARGS )
{
K_TREE * ktre e ;
K_TRE E * x , * y ;
K_TRE E * pp ;
K_NODE * knod e ;
K_NOD E * x , * y ;
K_NOD E * pp ;
cmp_t cmp ;
if ( roo t = = NULL )
FAIL ( " %s " , " ADDNULL add k tree is NULL " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " ADDNULL add tree is NULL " ) ;
//check_ktree(roo t, ">add", NULL, 1, 1, 1, KTREE_FFL_PASS);
//check_ktree(tree , ">add", NULL, 1, 1, 1, KTREE_FFL_PASS);
if ( root - > parent ! = nil & & root - > parent ! = NULL )
FAIL ( " %s " , " ADDROOT add root isn't the root " ) ;
if ( tree - > root - > parent ! = nil & & tree - > root - > parent ! = NULL )
FAIL ( " %s " , " ADDROOT add tree-> root isn't the root " ) ;
ktre e = new_data ( data , KTREE_FFL_PASS ) ;
knod e = new_data ( data , KTREE_FFL_PASS ) ;
if ( root - > isNil = = Yo )
if ( tree - > root - > isNil = = Yo )
{
if ( root ! = nil )
free ( root ) ;
if ( tree - > root ! = nil )
free ( tree - > root ) ;
root = ktre e ;
tree - > root = knod e ;
}
else
{
x = root ;
x = tree - > root ;
y = nil ;
while ( x - > isNil = = No )
{
y = x ;
if ( ( cmp = ( * cmp_funct ) ( ktre e- > data , x - > data ) ) < 0 )
if ( ( cmp = tree - > cmp_funct ( knod e- > data , x - > data ) ) < 0 )
x = x - > left ;
else
x = x - > right ;
}
ktre e - > parent = y ;
knod e - > parent = y ;
if ( cmp < 0 )
y - > left = ktre e ;
y - > left = knod e ;
else
y - > right = ktre e ;
y - > right = knod e ;
x = ktre e ;
while ( x ! = root & & x - > parent - > red = = RED_RED )
x = knod e ;
while ( x ! = tree - > root & & x - > parent - > red = = RED_RED )
{
pp = x - > parent - > parent ;
if ( x - > parent = = pp - > left )
@ -519,12 +543,12 @@ K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K
if ( x = = x - > parent - > right )
{
x = x - > parent ;
root = left_rotate ( root , x ) ;
tree - > root = left_rotate ( tree - > root , x ) ;
pp = x - > parent - > parent ;
}
x - > parent - > red = RED_BLACK ;
pp - > red = RED_RED ;
root = right_rotate ( root , pp ) ;
tree - > root = right_rotate ( tree - > root , pp ) ;
}
}
else
@ -542,45 +566,49 @@ K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K
if ( x = = x - > parent - > left )
{
x = x - > parent ;
root = right_rotate ( root , x ) ;
tree - > root = right_rotate ( tree - > root , x ) ;
pp = x - > parent - > parent ;
}
x - > parent - > red = RED_BLACK ;
pp - > red = RED_RED ;
root = left_rotate ( root , pp ) ;
tree - > root = left_rotate ( tree - > root , pp ) ;
}
}
}
}
root - > red = RED_BLACK ;
//check_ktree(root, "<add", NULL, 1, 1, 1, KTREE_FFL_PASS);
tree - > root - > red = RED_BLACK ;
return ( root ) ;
//check_ktree(tree, "<add", NULL, 1, 1, 1, KTREE_FFL_PASS);
}
K_ITEM * _find_in_ktree ( K_TREE * k tree, K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
K_ITEM * _find_in_ktree ( K_TREE * tree , K_ITEM * data , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_NODE * knode ;
cmp_t cmp = - 1 ;
if ( ktree = = NULL )
FAIL ( " %s " , " FINDNULL find ktree is NULL " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " FINDNULL find tree is NULL " ) ;
if ( tree - > root = = NULL )
FAIL ( " %s " , " FINDNULL find tree->root is NULL " ) ;
while ( ktree - > isNil = = No & & cmp ! = 0 )
knode = tree - > root ;
while ( knode - > isNil = = No & & cmp ! = 0 )
{
if ( ( cmp = ( * cmp_funct ) ( ktree - > data , data ) ) )
if ( ( cmp = tree - > cmp_funct ( knod e- > data , data ) ) )
{
if ( cmp > 0 )
ktree = ktre e - > left ;
knode = knod e - > left ;
else
ktree = ktre e - > right ;
knode = knod e - > right ;
}
}
if ( ktre e - > isNil = = No )
if ( knod e - > isNil = = No )
{
* ctx = ktre e ;
return ( ktre e - > data ) ;
* ctx = knod e ;
return ( knod e - > data ) ;
}
else
{
@ -589,30 +617,35 @@ K_ITEM *_find_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *,
}
}
K_ITEM * _find_after_in_ktree ( K_TREE * k tree, K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
K_ITEM * _find_after_in_ktree ( K_TREE * tree , K_ITEM * data , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_TREE * old = NULL ;
K_NODE * knode , * old = NULL ;
cmp_t cmp = - 1 , oldcmp = - 1 ;
if ( ktree = = NULL )
FAIL ( " %s " , " FINDNULL find_after ktree is NULL " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " FINDNULL find_after tree is NULL " ) ;
if ( tree - > root = = NULL )
FAIL ( " %s " , " FINDNULL find_after tree->root is NULL " ) ;
while ( ktree - > isNil = = No & & cmp ! = 0 )
knode = tree - > root ;
while ( knode - > isNil = = No & & cmp ! = 0 )
{
if ( ( cmp = ( * cmp_funct ) ( ktree - > data , data ) ) )
if ( ( cmp = tree - > cmp_funct ( knod e- > data , data ) ) )
{
old = ktre e ;
old = knod e ;
oldcmp = cmp ;
if ( cmp > 0 )
ktree = ktre e - > left ;
knode = knod e - > left ;
else
ktree = ktre e - > right ;
knode = knod e - > right ;
}
}
if ( ktre e - > isNil = = No )
if ( knod e - > isNil = = No )
{
* ctx = ktre e ;
* ctx = knod e ;
return next_in_ktree ( ctx ) ;
}
else
@ -634,30 +667,35 @@ K_ITEM *_find_after_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_I
}
}
K_ITEM * _find_before_in_ktree ( K_TREE * k tree, K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
K_ITEM * _find_before_in_ktree ( K_TREE * tree , K_ITEM * data , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_TREE * old = NULL ;
K_NODE * knode , * old = NULL ;
cmp_t cmp = 1 , oldcmp = 1 ;
if ( ktree = = NULL )
FAIL ( " %s " , " FINDNULL find_before ktree is NULL " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " FINDNULL find_before tree is NULL " ) ;
if ( tree - > root = = NULL )
FAIL ( " %s " , " FINDNULL find_before tree->root is NULL " ) ;
knode = tree - > root ;
while ( ktree - > isNil = = No & & cmp ! = 0 )
while ( knod e - > isNil = = No & & cmp ! = 0 )
{
if ( ( cmp = ( * cmp_funct ) ( ktree - > data , data ) ) )
if ( ( cmp = tree - > cmp_funct ( knod e- > data , data ) ) )
{
old = ktre e ;
old = knod e ;
oldcmp = cmp ;
if ( cmp > 0 )
ktree = ktre e - > left ;
knode = knod e - > left ;
else
ktree = ktre e - > right ;
knode = knod e - > right ;
}
}
if ( ktre e - > isNil = = No )
if ( knod e - > isNil = = No )
{
* ctx = ktre e ;
* ctx = knod e ;
return prev_in_ktree ( ctx ) ;
}
else
@ -679,9 +717,9 @@ K_ITEM *_find_before_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_
}
}
static K_TRE E * removeFixup ( K_TRE E * root , K_TRE E * fix )
static K_NOD E * removeFixup ( K_NOD E * root , K_NOD E * fix )
{
K_TRE E * w = NULL ;
K_NOD E * w = NULL ;
while ( fix ! = root & & fix - > red ! = RED_RED )
{
@ -758,37 +796,40 @@ static K_TREE *removeFixup(K_TREE *root, K_TREE *fix)
return root ;
}
// Does this work OK when you remove the last element in the k tree?
// Does this work OK when you remove the last element in the tree?
// It should return the root as 'nil'
K_TREE * _remove_from_ktree ( K_TREE * roo t, K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
void _remove_from_ktree ( K_TREE * tree , K_ITEM * data , K_TREE_CTX * ctx , KTREE_FFL_ARGS )
{
K_TREE_CTX tmpctx [ 1 ] ;
K_TRE E * found ;
K_NOD E * found ;
K_ITEM * fdata ;
K_TRE E * x , * y , * nil2 ;
K_NOD E * x , * y , * nil2 ;
// cmp_t cmp;
int yred ;
//check_ktree(roo t, ">remove", NULL, 1, 1, 1, KTREE_FFL_PASS);
//check_ktree(tree , ">remove", NULL, 1, 1, 1, KTREE_FFL_PASS);
if ( roo t = = NULL )
FAIL ( " %s " , " REMNULL remove k tree is NULL " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " REMNULL remove tree is NULL " ) ;
if ( root - > isNil = = Yo )
if ( tree - > root = = NULL )
FAIL ( " %s " , " REMNULL remove tree->root is NULL " ) ;
if ( tree - > root - > isNil = = Yo )
{
* ctx = NULL ;
return ( root ) ;
return ;
}
if ( root - > parent - > isNil = = No )
FAIL ( " %s " , " REMROOT remove root isn't the root " ) ;
if ( tree - > root - > parent - > isNil = = No )
FAIL ( " %s " , " REMROOT remove tree-> root isn't the root " ) ;
fdata = find_in_ktree ( roo t, data , cmp_funct , ctx ) ;
fdata = find_in_ktree ( tree , data , ctx ) ;
if ( fdata = = NULL )
return ( root ) ;
return ;
if ( cmp_funct ( fdata , data ) ! = 0 )
if ( tree - > cmp_funct ( fdata , data ) ! = 0 )
FAIL ( " %s " , " BADFIND cmp(found, remove) != 0 " ) ;
found = * ctx ;
@ -819,14 +860,14 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM
nil2 = NULL ;
else
{
nil2 = new_ktree ( ) ;
nil2 = _new_knode ( KTREE_FFL_PASS ) ;
x = nil2 ;
}
x - > parent = y - > parent ;
if ( x - > parent - > isNil = = Yo )
root = x ;
tree - > root = x ;
else
{
if ( x - > parent - > left = = y )
@ -837,8 +878,8 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM
if ( y ! = found )
{
if ( root = = found )
root = y ;
if ( tree - > root = = found )
tree - > root = y ;
if ( x = = found )
x = y ;
@ -864,7 +905,7 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM
}
if ( yred ! = RED_RED )
root = removeFixup ( root , x ) ;
tree - > root = removeFixup ( tree - > root , x ) ;
if ( nil2 ! = NULL )
{
@ -874,8 +915,8 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM
if ( nil2 - > parent - > isNil = = No & & nil2 - > parent - > right = = nil2 )
nil2 - > parent - > right = nil ;
if ( root = = nil2 )
root = nil ;
if ( tree - > root = = nil2 )
tree - > root = nil ;
/*
if ( dbg ! = 0 )
@ -889,24 +930,24 @@ DBG("@remove nil2->left wasn't nil!!!\n");
DBG ( " @remove nil2->right wasn't nil!!! \n " ) ;
}
cmp = 0 ;
fdata = first_in_ktree ( roo t, tmpctx ) ; ;
fdata = first_in_ktree ( tree , tmpctx ) ; ;
while ( fdata ! = NULL )
{
cmp + + ;
x = * tmpctx ;
if ( x = = nil2 )
{
DBG ( " @remove found nil2 in ktree %f !!! \n " , cmp ) ;
DBG ( " @remove found nil2 in ktree %d !!! \n " , ( int ) cmp ) ;
}
else
if ( x - > left = = nil2 )
{
DBG ( " @remove found nil2 in ktree(left) %f !!! \n " , cmp ) ;
DBG ( " @remove found nil2 in ktree(left) %d !!! \n " , ( int ) cmp ) ;
}
else
if ( x - > right = = nil2 )
{
DBG ( " @remove found nil2 in ktree(right) %f !!! \n " , cmp ) ;
DBG ( " @remove found nil2 in ktree(right) %d !!! \n " , ( int ) cmp ) ;
}
fdata = next_in_ktree ( tmpctx ) ; ;
@ -920,10 +961,10 @@ DBG("@remove found nil2 in ktree(right) %f!!!\n", cmp);
if ( dbg ! = 0 )
{
cmp = 0 ;
fdata = first_in_ktree ( roo t, tmpctx ) ; ;
fdata = first_in_ktree ( tree , tmpctx ) ; ;
while ( fdata ! = NULL )
{
if ( cmp_funct ( fdata , root - > data ) < 0 )
if ( tree - > cmp_funct ( fdata , tree - > root - > data ) < 0 )
cmp - - ;
else
cmp + + ;
@ -932,52 +973,48 @@ if (dbg != 0)
}
if ( cmp < - 10 | | cmp > 10 )
{
DBG ( " @remove after balance=%f :( \n " , cmp ) ;
DBG ( " @remove after balance=%d :( \n " , ( int ) cmp ) ;
}
}
*/
//check_ktree(roo t, "<remove", NULL, 1, 1, 1, KTREE_FFL_PASS);
//check_ktree(tree , "<remove", NULL, 1, 1, 1, KTREE_FFL_PASS);
return root ;
return ;
}
K_TREE * _remove_from_ktree_free ( K_TREE * root , K_ITEM * data , cmp_t ( * cmp_funct ) ( K_ITEM * , K_ITEM * ) , KTREE_FFL_ARGS )
void _remove_from_ktree_free ( K_TREE * root , K_ITEM * data , KTREE_FFL_ARGS )
{
K_TREE_CTX ctx [ 1 ] ;
root = _remove_from_ktree ( root , data , cmp_funct , ctx , KTREE_FFL_PASS ) ;
_remove_from_ktree ( root , data , ctx , KTREE_FFL_PASS ) ;
if ( * ctx )
free ( * ctx ) ;
return root ;
}
static void free_ktree_sub ( K_TREE * ktre e , void ( * free_funct ) ( void * ) )
static void free_ktree_sub ( K_NODE * knod e , void ( * free_funct ) ( void * ) )
{
if ( ktre e ! = NULL & & ktre e ! = nil )
if ( knod e ! = NULL & & knod e ! = nil )
{
if ( ktre e - > data ! = NULL & & free_funct )
( * free_funct ) ( ktre e- > data ) ;
if ( knod e - > data ! = NULL & & free_funct )
free_funct ( knod e- > data ) ;
free_ktree_sub ( ktre e - > left , free_funct ) ;
free_ktree_sub ( ktre e - > right , free_funct ) ;
free_ktree_sub ( knod e - > left , free_funct ) ;
free_ktree_sub ( knod e - > right , free_funct ) ;
free ( ktre e ) ;
free ( knod e ) ;
}
}
K_TREE * _free_ktree ( K_TREE * k tree, void ( * free_funct ) ( void * ) , KTREE_FFL_ARGS )
void _free_ktree ( K_TREE * tree , void ( * free_funct ) ( void * ) , KTREE_FFL_ARGS )
{
if ( ktree = = NULL )
FAIL ( " %s " , " FREENULL free NULL ktree " ) ;
if ( ktree - > parent ! = NULL & & ktree - > parent ! = nil )
FAIL ( " %s " , " FREENOTROOT free ktree not root " ) ;
if ( tree = = NULL )
FAIL ( " %s " , " FREENULL free NULL tree " ) ;
free_ktree_sub ( ktree , free_funct ) ;
if ( tree - > root - > parent ! = NULL & & tree - > root - > parent ! = nil )
FAIL ( " %s " , " FREENOTROOT free tree->root not root " ) ;
return ( nil ) ;
free_ktree_sub ( tree - > root , free_funct ) ;
}