Exemplo n.º 1
0
/*!
 * Duplicate the entire sub-tree rooted at the given node
 *
 * \param node The sub-tree root
 *
 * \return A pointer to the duplicated sub-tree root
 */
rbnode_t * rbnode_duplicate
    (
    rbnode_t * node
    )
    {
    /* Create a node of the same color, containing the same object */
    rbnode_t * dup_node = rbnode_create(node->object, node->color);

    if (!dup_node)
        return NULL;

    /* Duplicate the children recursively */
    if (node->right)
        {
        dup_node->right = rbnode_duplicate (node->right);
        dup_node->right->parent = dup_node;
        }
    else
        {
        dup_node->right = NULL;
        }

    if (node->left)
        {
        dup_node->left = rbnode_duplicate(node->left);
        dup_node->left->parent = dup_node;
        }
    else
        {
        dup_node->left = NULL;
        }

    /* Return the duplicated node */
    return dup_node;
    }
Exemplo n.º 2
0
void map_insert(map* tree, const char* key, void* data, const int tag) 
{
  rbnode* node = rbnode_create(key, data, tag);
  rbnode* iterator;
  int     comparison;
  int     fail = 0;

  if (tree->root == 0) 
  {
    tree_set_root(tree, node);
    tree->size = 0;
  }
  else 
  {
    iterator = tree->root;
    while (iterator != 0) 
    {
      comparison = strcmp(key, iterator->data.key);

      /* key already exists */
      if (comparison == 0) 
      {
        fail = 1;
        iterator = 0;
      }
      /* new key < iterator's key */
      else if (comparison < 0) 
      {
        /* left of iterator is free */
        if (iterator->left != 0) 
        {
          iterator = iterator->left;
        } 
        /* left of iterator is occupied */
        else 
        {
          rbnode_set_left_child(iterator, node);
          iterator = 0;
        }
      }
      /* new key > iterator's key */
      else 
      {
        /* right of iterator is free */
        if (iterator->right != 0) 
        {
          iterator = iterator->right;
        }
        /* right of iterator is occupied */
        else 
        {
          rbnode_set_right_child(iterator, node);
          iterator = 0;
        }
      }
    }
  }

  /* tree requires rebalancing */
  if (!fail) 
  {
    tree->size++;
    map_insert_balance(tree, node);
  }
}
Exemplo n.º 3
0
/*! 
 * Insert a new object to the tree as the a predecessor of a given node
 *
 * \param tree The tree
 *
 * \return The new node
 */
rbnode_t * rbtree_insert_predecessor_object_at
    (
    rbtree_t * tree,
    rbnode_t * at_node, 
    void * object
    )
    {
    rbnode_t * parent;
    rbnode_t * new_node;

    if (!(tree->root))
        {
        /* Assign a new root node. Notice that the root is always black */
        new_node = rbnode_create(object, RB_BLACK);
        
        if (!new_node) 
            return NULL;
        
        tree->root = new_node;
        tree->size = 1;

        new_node->tree = tree;
        
        return new_node;
        }

    /* Insert the new object as a red leaf, being the predecessor of at_node */
    new_node = rbnode_create(object, RB_RED);
    
    if (!new_node) 
        return NULL;

    if (!at_node)
        {
        /* The new node should become the tree maximum: Place is as the right
         * child of the current maximal leaf.
         */
        parent = rbnode_maximum(tree->root);
        parent->right = new_node;
        }
    else
        {
        /* Make sure the insertion does not violate the tree order */

        /* In case given node has no left child, place the new node as its
         * left child. Otherwise, place it at the rightmost position at the
         * sub-tree rooted at its left side.
         */
        if (!(at_node->left))
            {
            parent = at_node;
            parent->left = new_node;
            }
        else
            {
            parent = rbnode_maximum (at_node->left);
            parent->right = new_node;
            }
        }

    new_node->parent = parent;

    /* Mark that a new node was added */
    tree->size++;

    /* Fix up the tree properties */
    rbtree_insert_fixup(tree, new_node);

    new_node->tree = tree;

    return new_node;
    }
Exemplo n.º 4
0
/*!
 * Insert an object to the tree [takes O(log n) operations]
 *
 * \param tree The tree
 *
 * \param object The object to be inserted
 *
 * \return the inserted object node
 */
rbnode_t * rbtree_insert_object
    (
    rbtree_t * tree, 
    void * object
    )
    {
    rbnode_t * cur_node;
    rbnode_t * new_node;

    if (!(tree->root))
        {
        /*
         * Assign a new root node.
         * Notice that the root is always black
         */
        new_node = rbnode_create(object, RB_BLACK);

        if (!new_node)
            return NULL;

        tree->root = new_node;
        tree->size = 1;
        
        new_node->tree = tree;
        
        return new_node;
        }

    /* Find a place for the new object, and insert it as a red leaf */
    cur_node = tree->root;

    new_node = rbnode_create(object, RB_RED);
    if (!new_node)
        return NULL;

    while (cur_node)
        {
        /*
         * Compare inserted object with the object stored
         * in the current node
         */
        if ((tree->compare)(object, cur_node->object) > 0)
            {
            if (!(cur_node->left))
                {
                /*
                 * Insert the new leaf as the left
                 * child of the current node
                 */
                cur_node->left = new_node;
                new_node->parent = cur_node;

                /* Terminate the while loop */
                cur_node = NULL;
                }
            else
                {
                /* Go to the left sub-tree */
                cur_node = cur_node->left;
                }
            }
        else
            {
            if (!(cur_node->right))
                {
                /*
                 * Insert the new leaf as the right
                 * child of the current node
                 */
                cur_node->right = new_node;
                new_node->parent = cur_node;

                /* Terminate the while loop */
                cur_node = NULL;
                }
            else
                {
                /* Go to the right sub-tree */
                cur_node = cur_node->right;
                }
            }
        }

    /* Mark that a new node was added */
    tree->size++;

    /* Fix up the tree properties */
    rbtree_insert_fixup(tree, new_node);
    
    new_node->tree = tree;
    
    return new_node;
    }