AVLTree
view release on metacpan or search on metacpan
avltree/avltree.c view on Meta::CPAN
up[top++] = heir;
heir = heir->link[0];
}
/* Swap data */
save = it->data;
it->data = heir->data;
heir->data = save;
/* Unlink successor and fix parent */
up[top - 1]->link[up[top - 1] == it] = heir->link[1];
tree->rel ( heir->data );
free ( heir );
}
/* Walk back up the search path */
while ( --top >= 0 && !done ) {
/* Update balance factors */
up[top]->balance += upd[top] != 0 ? -1 : +1;
/* Terminate or rebalance as necessary */
if ( abs ( up[top]->balance ) == 1 )
break;
else if ( abs ( up[top]->balance ) > 1 ) {
remove_balance ( up[top], upd[top], done );
/* Fix parent */
if ( top != 0 )
up[top - 1]->link[upd[top - 1]] = up[top];
else
tree->root = up[0];
}
}
--tree->size;
}
return 1;
}
size_t avltree_size ( avltree_t *tree )
{
return tree->size;
}
avltrav_t *avltnew ( void )
{
return malloc ( sizeof ( avltrav_t ) );
}
void avltdelete ( avltrav_t *trav )
{
free ( trav );
}
/*
First step in traversal,
handles min and max
*/
static SV *start (pTHX_ avltrav_t *trav, avltree_t *tree, int dir )
{
trav->tree = tree;
trav->it = tree->root;
trav->top = 0;
/* Build a path to work with */
if ( trav->it != NULL ) {
while ( trav->it->link[dir] != NULL ) {
trav->path[trav->top++] = trav->it;
trav->it = trav->it->link[dir];
}
}
return trav->it == NULL ? &PL_sv_undef : trav->it->data;
}
/*
Subsequent traversal steps,
handles ascending and descending
*/
static SV *move (pTHX_ avltrav_t *trav, int dir )
{
if ( trav->it->link[dir] != NULL ) {
/* Continue down this branch */
trav->path[trav->top++] = trav->it;
trav->it = trav->it->link[dir];
while ( trav->it->link[!dir] != NULL ) {
trav->path[trav->top++] = trav->it;
trav->it = trav->it->link[!dir];
}
}
else {
/* Move to the next branch */
avlnode_t *last;
do {
if ( trav->top == 0 ) {
trav->it = NULL;
break;
}
last = trav->it;
trav->it = trav->path[--trav->top];
} while ( last == trav->it->link[dir] );
}
return trav->it == NULL ? &PL_sv_undef : trav->it->data;
}
SV *avltfirst (pTHX_ avltrav_t *trav, avltree_t *tree )
{
return start (aTHX_ trav, tree, 0 ); /* Min value */
}
SV *avltlast (pTHX_ avltrav_t *trav, avltree_t *tree )
{
return start (aTHX_ trav, tree, 1 ); /* Max value */
}
SV *avltnext (pTHX_ avltrav_t *trav )
{
return move (aTHX_ trav, 1 ); /* Toward larger items */
}
SV *avltprev (pTHX_ avltrav_t *trav )
{
return move (aTHX_ trav, 0 ); /* Toward smaller items */
}
( run in 1.068 second using v1.01-cache-2.11-cpan-39bf76dae61 )