return t->elem;
else if(t->child[0]||t->child[1]){
int i= !t->child[0];
- AVTreeNode **child= &t->child[i];
void *next_elem[2];
- av_tree_find(*child, key, cmp, next_elem);
+ av_tree_find(t->child[i], key, cmp, next_elem);
key= t->elem= next_elem[i];
v= -i;
}else{
if(!(t->state&1)){
if(t->state){
+ /* The following code is equivalent to
+ if((*child)->state*2 == -t->state)
+ rotate(child, i^1);
+ rotate(tp, i);
+
+ with rotate():
+ static void rotate(AVTreeNode **tp, int i){
+ AVTreeNode *t= *tp;
+
+ *tp= t->child[i];
+ t->child[i]= t->child[i]->child[i^1];
+ (*tp)->child[i^1]= t;
+ i= 4*t->state + 2*(*tp)->state + 12;
+ t ->state= ((0x614586 >> i) & 3)-1;
+ (*tp)->state= ((*tp)->state>>1) + ((0x400EEA >> i) & 3)-1;
+ }
+ but such a rotate function is both bigger and slower
+ */
if((*child)->state*2 == -t->state){
*tp= (*child)->child[i^1];
(*child)->child[i^1]= (*tp)->child[i];
return ret;
}else{
*tp= *next; *next= NULL;
- (*tp)->elem= key;
- return NULL;
+ if(*tp){
+ (*tp)->elem= key;
+ return NULL;
+ }else
+ return key;
}
}
void av_tree_destroy(AVTreeNode *t){
- av_tree_destroy(t->child[0]);
- av_tree_destroy(t->child[1]);
- av_free(t);
+ if(t){
+ av_tree_destroy(t->child[0]);
+ av_tree_destroy(t->child[1]);
+ av_free(t);
+ }
}
#if 0
}
int main(void){
- int i,j,k;
+ int i,k;
AVTreeNode *root= NULL, *node=NULL;
for(i=0; i<10000; i++){
av_tree_insert(&root, (void*)(j+1), cmp, &node);
j= (random()%86294);
- k= av_tree_find(root, (void*)(j+1), cmp, NULL);
- if(k){
+ {
AVTreeNode *node2=NULL;
+ av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j);
av_tree_insert(&root, (void*)(j+1), cmp, &node2);
k= av_tree_find(root, (void*)(j+1), cmp, NULL);
if(k)
- av_log(NULL, AV_LOG_ERROR, "removial failure %d\n", i);
+ av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
}
}
return 0;