int avl_get_span_by_two_keys (avl_tree * tree, void * low_key, void * high_key, unsigned long * low, unsigned long * high) { unsigned long i, j; avl_node * low_node, * high_node; int order; /* we may need to swap them */ order = tree->compare_fun (tree->compare_arg, low_key, high_key); if (order > 0) { void * temp = low_key; low_key = high_key; high_key = temp; } low_node = avl_get_index_by_key (tree, low_key, &i); high_node = avl_get_index_by_key (tree, high_key, &j); if (low_node) { avl_node * left; /* search left */ left = avl_get_predecessor (low_node); while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, low_key, left->key) == 0)) { left = avl_get_predecessor (left); i = i - 1; } } else { i = i + 1; } if (high_node) { avl_node * right; /* search right */ right = avl_get_successor (high_node); if (right == tree->root) { // special case, tree->size == 1 j = i + 1; } else { while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, high_key, right->key) == 0)) { right = avl_get_successor (right); j = j + 1; } } } else { j = j + 1; } *low = i; *high = j; return 0; }
void avl_test_insert() { avlTree_t tree; avlNode_t *node; int_t i; avl_init(&tree); for(i = 0; i < 10240; ++i) { avl_insert_equal(&tree, rand()%999999); } avl_print_tree(&tree); if(!avl_verify_tree(&tree)) { AR_ASSERT(false); } node = tree.left_most; while(node) { AR_printf(L"%d\r\n", node->data); node = avl_get_successor(node); } AR_printf(L"\r\n"); avl_uninit(&tree); }
int avl_get_span_by_key (avl_tree * tree, void * key, unsigned long * low, unsigned long * high) { unsigned long m, i, j; avl_node * node; node = avl_get_index_by_key (tree, key, &m); /* did we find an exact match? * if so, we have to search left and right * to find the span, since we know nothing about * the arrangement of like keys. */ if (node) { avl_node * left, * right; /* search left */ left = avl_get_predecessor (node); i = m; while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, key, left->key) == 0)) { left = avl_get_predecessor (left); i = i - 1; } /* search right */ right = avl_get_successor (node); if (right == tree->root) { // special case, tree->size == 1 *low = i; *high = i + 1; return 0; } else { j = m; while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, key, right->key) == 0)) { right = avl_get_successor (right); j = j + 1; } *low = i; *high = j + 1; return 0; } } else { *low = *high = m; } return 0; }
bool_t avl_verify_tree(const avlTree_t *tree) { avlNode_t *curr; AR_ASSERT(tree != NULL); curr = __get_min(tree->root); while(curr) { int_t l = __calc_height(curr->child[AVL_LEFT]); int_t r = __calc_height(curr->child[AVL_RIGHT]); if(curr->bf != (r - l)) { return false; } if(curr->child[AVL_LEFT] != NULL) { if(curr->child[AVL_LEFT]->data > curr->data) { return false; } } if(curr->child[AVL_RIGHT] != NULL) { if(curr->data > curr->child[AVL_RIGHT]->data ) { return false; } } if(curr->child[AVL_LEFT] && curr->child[AVL_RIGHT]) { if(curr->child[AVL_LEFT]->data > curr->child[AVL_RIGHT]->data) { return false; } } curr = avl_get_successor(curr); } return true; }
static AR_INLINE avlNode_t* __unlink_node(avlNode_t *node, avlNode_t **proot, avlNode_t **pleft_most, avlNode_t **pright_most) { avlNode_t *rm, *chd, *p; int_t bf; AR_ASSERT(node != NULL && proot != NULL && *proot != NULL && pleft_most != NULL && *pleft_most != NULL && pright_most != NULL && *pright_most != NULL); rm = node; chd = NULL; p = NULL; bf = 0; if(rm->child[AVL_LEFT] == NULL) { chd = rm->child[AVL_RIGHT]; }else { if(rm->child[AVL_RIGHT] == NULL) { chd = rm->child[AVL_LEFT]; }else { rm = avl_get_successor(rm); chd = rm->child[AVL_RIGHT]; } } if(rm != node) { rm->child[AVL_LEFT] = node->child[AVL_LEFT]; rm->child[AVL_LEFT]->parent = rm; if(rm != node->child[AVL_RIGHT]) { p = rm->parent; p->child[AVL_LEFT] = chd; if(chd != NULL)chd->parent = p; rm->child[AVL_RIGHT] = node->child[AVL_RIGHT]; rm->child[AVL_RIGHT]->parent = rm; bf = -1; }else { p = rm; bf = 1; } if(node == *proot) { *proot = rm; }else if(node == node->parent->child[AVL_LEFT]) { node->parent->child[AVL_LEFT] = rm; }else { node->parent->child[AVL_RIGHT] = rm; } rm->parent = node->parent; { int_t bf = rm->bf; rm->bf = node->bf; node->bf = bf; } }else { p = node->parent; if(chd != NULL) chd->parent = p; if(node == *proot) { *proot = chd; }else if(node == p->child[AVL_LEFT]) { p->child[AVL_LEFT] = chd; bf = -1; }else { p->child[AVL_RIGHT] = chd; bf = 1; } if(node == *pleft_most) { if(node->child[AVL_RIGHT] == NULL) { *pleft_most = p; }else { *pleft_most = __get_min(chd); } } if(node == *pright_most) { if(node->child[AVL_LEFT] == NULL) { *pright_most = p; }else { *pright_most = __get_max(node->child[AVL_LEFT]); } } } __fixup(p, proot, bf, AVL_ERASE); return node; }