GAULFUNC boolean avltree_insert(AVLTree *tree, vpointer data) { boolean inserted=FALSE; if (!tree) return FALSE; if (!data) return FALSE; /* ordered search would barf at this! */ tree->root = avltree_node_insert(tree->root, tree->key_generate_func(data), data, &inserted); return inserted; }
bool test_avltree() { unsigned int i, list[8] = { 4, 2, 3, 7, 1, 0, 6, 5 }, trim[5] = { 1, 2, 5, 6, 7 }; struct avltree_node_t *root = NULL, *cur, node[10000]; printf("testing avltree... "); { for(i = 0; i < 8; i++) avltree_node_insert(&root, &node[list[i]], (avltree_compare_nodenode_f)compare_ptr, NULL); for(i = 0, cur = avltree_node_first(root); i < 8; i++, cur = avltree_node_next(cur)) { if(cur != &node[i]) return printf("failed\n"), false; } avltree_node_remove(&root, &node[list[2]], (avltree_compare_nodekey_f)compare_ptr, NULL); avltree_node_remove(&root, &node[list[5]], (avltree_compare_nodekey_f)compare_ptr, NULL); avltree_node_remove(&root, &node[list[0]], (avltree_compare_nodekey_f)compare_ptr, NULL); for(i = 0, cur = avltree_node_first(root); i < 5; i++, cur = avltree_node_next(cur)) { if(cur != &node[trim[i]]) return printf("failed\n"), false; } } { root = NULL; for(i = 0; i < 1000; i++) avltree_node_insert(&root, &node[i*443%1000], (avltree_compare_nodenode_f)compare_ptr, NULL); for(i = 0, cur = avltree_node_first(root); i < 1000; i++, cur = avltree_node_next(cur)) { if(cur != &node[i]) return printf("failed\n"), false; else if((cur->balance < -1) || (cur->balance > 1)) return printf("failed\n"), false; } } { root = NULL; for(i = 0; i < 10000; i++) avltree_node_insert(&root, &node[i*5333%10000], (avltree_compare_nodenode_f)compare_ptr, NULL); for(i = 10000 - 1, cur = avltree_node_last(root); i != UINT_MAX; i--, cur = avltree_node_prev(cur)) { if(cur != &node[i]) return printf("failed\n"), false; else if((cur->balance < -1) || (cur->balance > 1)) return printf("failed\n"), false; } for(i = 1; i < 10000; i++) { if(avltree_node_atmost(root, (void *)&node[i] - 1, (avltree_compare_nodekey_f)compare_ptr, NULL) != &node[i - 1]) return printf("failed\n"), false; } for(i = 0; i < 10000 - 1; i++) { if(avltree_node_atleast(root, (void *)&node[i] + 1, (avltree_compare_nodekey_f)compare_ptr, NULL) != &node[i + 1]) return printf("failed\n"), false; } } printf("okay\n"); return true; }
static AVLNode *avltree_node_insert(AVLNode *node, AVLKey key, vpointer data, boolean *inserted) { int old_balance; if (!node) { *inserted = TRUE; return avltree_node_new(key, data); } if (key < node->key) { if (node->left!=NULL) { old_balance = node->left->balance; node->left = avltree_node_insert(node->left, key, data, inserted); if ((old_balance != node->left->balance) && node->left->balance) node->balance--; } else { *inserted = TRUE; node->left = avltree_node_new(key, data); node->balance--; } } else if (key > node->key) { if (node->right!=NULL) { old_balance = node->right->balance; node->right = avltree_node_insert(node->right, key, data, inserted); if ((old_balance != node->right->balance) && node->right->balance) node->balance++; } else { *inserted = TRUE; node->right = avltree_node_new(key, data); node->balance++; } } else { /* key == node->key */ /* *inserted = FALSE; */ printf("WARNING: -- Replaced node -- (Key clash?)\n"); node->data = data; return node; } if (*inserted!=FALSE && (node->balance < -1 || node->balance > 1)) node = avltree_node_balance(node); return node; }