avl_tree insert_avl_tree(avl_tree avltr, ElementType e) { if ( avltr == NULL ) { avltr = (avl_tree)malloc( sizeof(struct AvlNode) ); avltr->element = e; avltr->height = 0; avltr->left = avltr->right = NULL; } else if ( avltr->element >= e ) { //to left avltr->left = insert_avl_tree(avltr->left, e); if ( height_avl_tree(avltr->left) - height_avl_tree(avltr->right) == 2 ) { if ( avltr->left->element >= e ) { avltr = single_rotate_with_left(avltr); } else { avltr = double_rotate_with_left(avltr); } } } else if ( avltr->element < e ) { //to right avltr->right = insert_avl_tree(avltr->right, e); avltr->height ++; if ( height_avl_tree(avltr->right) - height_avl_tree(avltr->left) == 2 ) { if ( avltr->right->element < e ) { avltr = single_rotate_with_right(avltr); } else { avltr = double_rotate_with_right(avltr); } } } avltr->height = fmaxf(height_avl_tree(avltr->left), height_avl_tree(avltr->right)) + 1; return avltr; }
/* Insert a new node into the tree. */ node* insert (node *entry_node, node *current_node) { if (current_node == NULL) { current_node = entry_node; } else if (entry_node->sequence.len - current_node->sequence.len > 0) { current_node->left = insert (entry_node, current_node->left); if (height (current_node->left) - height (current_node->right) == 2) { if (entry_node->sequence.len - current_node->left->sequence.len > 0) { current_node = single_rotate_with_left (current_node); } else { current_node = double_rotate_with_left (current_node); } } } else if (entry_node->sequence.len - current_node->sequence.len <= 0) { current_node->right = insert (entry_node, current_node->right); if (height (current_node->right) - height (current_node->left) == 2) { if (entry_node->sequence.len - current_node->right->sequence.len <= 0) { current_node = single_rotate_with_right (current_node); } else { current_node = double_rotate_with_right (current_node); } } } current_node->height = max (height (current_node->left), height (current_node->right)) + 1; return current_node; }
static NodeEntry double_rotate_with_right( NodeEntry K1 ) { /* Rotate between K3 and K2 */ K1->right = single_rotate_with_left( K1->right ); /* Rotate between K1 and K2 */ return single_rotate_with_right( K1 ); }
static NodeEntry double_rotate_with_left( NodeEntry K3 ) { /* Rotate between K1 and K2 */ K3->left = single_rotate_with_right( K3->left ); /* Rotate between K3 and K2 */ return single_rotate_with_left( K3 ); }
AvlTree AVL_insert( u_long key, uint16_t port, struct pbsnode *node, AvlTree tree ) { if (tree == NULL) { /* Create and return a node */ if ((tree = ( AvlTree )calloc(1, sizeof( struct AvlNode ) )) == NULL) { return( tree ); } tree->key = key; tree->port = port; tree->pbsnode = node; tree->left = NULL; tree->right = NULL; tree->height = 0; } /* If key is less than current node value go left else go right. If equal compare port and go left or right accordingly */ if (key < tree->key) { tree->left = AVL_insert( key, port, node, tree->left ); if (height(tree->left) - height(tree->right) >= 2 ) { if (key <= tree->left->key ) tree = single_rotate_with_left( tree ); else tree = double_rotate_with_left( tree ); } } else if (key > tree->key ) { tree->right = AVL_insert( key, port, node, tree->right ); if (height(tree->right) - height(tree->left) >= 2 ) { if (key >= tree->right->key) tree = single_rotate_with_right( tree ); else tree = double_rotate_with_right( tree ); } } else { /* if it is in the tree, do not add it again */ if (port == tree->port) return(tree); /* the keys are equal. sort by port */ if (port != 0) { if (port < tree->port) { tree->left = AVL_insert( key, port, node, tree->left ); if (height(tree->left) - height(tree->right) >= 2) { if (port <= tree->left->port) tree = single_rotate_with_left( tree ); else tree = double_rotate_with_left( tree ); } } else if (port > tree->port ) { tree->right = AVL_insert( key, port, node, tree->right ); if (height(tree->right) - height(tree->left) >= 2) { if (port >= tree->right->port) tree = single_rotate_with_right( tree ); else tree = double_rotate_with_right( tree ); } } } } tree->height = Max(height(tree->left), height(tree->right)) + 1; return(tree); } /* End AVL_insert */
avl_tree double_rotate_with_right(avl_tree avltr) { avltr->right = single_rotate_with_left(avltr->right); avltr = single_rotate_with_right(avltr); return avltr; }
/* Right-left double rotation note: call double_rotate_with_right only if k1 has a right child and k1's right child has a left child. */ static node* double_rotate_with_right (node* k1) { /* rotate between K3 and k2 */ k1->right = single_rotate_with_left (k1->right); /* rotate between k1 and k2 */ return single_rotate_with_right (k1); }
/* Left-right double rotation note: call double_rotate_with_left only if k3 node has a left child and k3's left child has a right child. */ static node* double_rotate_with_left (node* k3) { /* Rotate between k1 and k2 */ k3->left = single_rotate_with_right (k3->left); /* Rotate between K3 and k2 */ return single_rotate_with_left (k3); }