void avl_insert(sb_avl * instance, void * key, void * data) { avl_node * curr_node, * prev_node, * q, * x, * y, * z; // insert into empty AVL tree if (avl_root(instance) == NULL) { instance->root = avl_new_node(key, data); instance->root->height = 1; return; } curr_node = instance->root; prev_node = instance->root; // traverse until NULL, keeping track of the parent while ( curr_node != NULL ) { if ( instance->cmp_keys(key, curr_node->key ) < 0 ) { prev_node = curr_node; // Remember prev. node curr_node = curr_node->left; // Continue search in left subtree } else if ( instance->cmp_keys(key, curr_node->key ) >= 0 ) { prev_node = curr_node; // Remember prev. node curr_node = curr_node->right; // Continue search in right subtree } } q = avl_new_node(key, data); q->height = 1; q->parent = prev_node; if ( instance->cmp_keys(key, prev_node->key) < 0 ) { prev_node->left = q; } else { prev_node->right = q; } x = y = z = q; while ( x != NULL ) { if ( avl_diff_height(x->left, x->right) <= 1) { z = y; y = x; x = x->parent; } else { break; } } if ( x != NULL ) { avl_trinode_restructure(instance, x, y, z); } return; }
/* insert an node to tree */ static avl_node_t* avl_insert_node(avl_node_t* root, avl_key_t key, void* data) { int rotate = 0; if (root == NULL) { return avl_new_node(key, data); } if (key < root->key) { rotate = ROT_LEFT; root->left = avl_insert_node(root->left, key, data); } else if (key > root->key) { rotate = ROT_RIGHT; root->right = avl_insert_node(root->right, key, data); } else assert(!"duplicated key insertion not supported"); /* update height */ root->height = MAX(HEIGHT(root->left), HEIGHT(root->right)) + 1; return avl_balance_node(root, avl_get_balance(root), rotate); }
extern int avl_insert(node_t **rootaddr, PyObject *key, PyObject *value) { node_t *root = *rootaddr; if (root == NULL) { root = avl_new_node(key, value); if (root == NULL) return -1; } else { node_t *it, *up[32]; int upd[32], top = 0; int done = 0; int cmp_res; it = root; for (;;) { cmp_res = ct_compare(KEY(it), key); if (cmp_res == 0) { Py_XDECREF(VALUE(it)); VALUE(it) = value; Py_INCREF(value); return 0; } upd[top] = (cmp_res < 0); up[top++] = it; if (it->link[upd[top - 1]] == NULL) break; it = it->link[upd[top - 1]]; } it->link[upd[top - 1]] = avl_new_node(key, value); if (it->link[upd[top - 1]] == NULL) return -1; while (--top >= 0 && !done) { int lh, rh, max; cmp_res = ct_compare(KEY(up[top]), key); lh = height(up[top]->link[upd[top]]); rh = height(up[top]->link[!upd[top]]); if (lh - rh == 0) done = 1; if (lh - rh >= 2) { node_t *a = up[top]->link[upd[top]]->link[upd[top]]; node_t *b = up[top]->link[upd[top]]->link[!upd[top]]; if (height( a ) >= height( b )) up[top] = avl_single(up[top], !upd[top]); else up[top] = avl_double(up[top], !upd[top]); if (top != 0) up[top - 1]->link[upd[top - 1]] = up[top]; else root = up[0]; done = 1; } lh = height(up[top]->link[upd[top]]); rh = height(up[top]->link[!upd[top]]); max = avl_max(lh, rh); BALANCE(up[top]) = max + 1; } } (*rootaddr) = root; return 1; }