Home > Software engineering >  Is it possible to optimize this recursive function?
Is it possible to optimize this recursive function?

Time:09-11

I am trying to understand if this is the fastest way possible to delete a node in the Tree.

struct node *deleteNode(struct node *root, char *key)
{
    // base case
    if (root == NULL)
        return root;

    // If the key to be deleted
    // is smaller than the root's
    // key, then it lies in left subtree
    if (strcmp(key, root->key) < 0)
        root->left = deleteNode(root->left, key);

    // If the key to be deleted
    // is greater than the root's
    // key, then it lies in right subtree
    else if (strcmp(key, root->key) > 0)
        root->right = deleteNode(root->right, key);

    // if key is same as root's key,
    // then This is the node
    // to be deleted
    else
    {
        // node with only one child or no child
        if (root->left == NULL)
        {
            struct node *temp = root->right;
            free(root);
            return temp;
        }
        else if (root->right == NULL)
        {
            struct node *temp = root->left;
            free(root);
            return temp;
        }

        // node with two children:
        // Get the inorder successor
        // (smallest in the right subtree)
        struct node *temp = minValueNode(root->right);

        // Copy the inorder
        // successor's content to this node
        root->key = temp->key;

        // Delete the inorder successor
        root->right = deleteNode(root->right, temp->key);
    }
    return root;
}

It takes a tree and a word and deletes the node from the tree. The thing I want to understand is when do I reach a "perfect" optimization level? I have worked a lot on this code and I think it is the best way possible. What can I look for more?

CodePudding user response:

First the initial parameter to deleteNode is the root, but you should actually name it just node or subtree.

You should free the key, and strdup the key on node creation.

Finding the value at that node you cannot immediately delete that node. Either look at the left's max value (left - rights - rightnull node) or rights min value (right - lefts - leftnull node).

You have three pointers, root, xnull node, and the xnull node's other subtree. One form of deleting is called rotating the pointers.

Notice you do copy the key. In C that could be more costly that a pointer copy. In C copying a pointer or at most a struct is similarly costly, though I would favor a pointer copy.

Then you descend the branch again, so there can be optimized a bit; at least more immediate.

struct node *deleteNode(struct node *tree, char *key)
{
    // base case
    if (tree == NULL)
        return tree;

    // If the key to be deleted
    // is smaller than the tree's
    // key, then it lies in left subtree
    int cmp = strcmp(key, tree->key); // Thanks to RachidK
    if (cmp < 0)
        tree->left = deleteNode(tree->left, key);

    // If the key to be deleted
    // is greater than the tree's
    // key, then it lies in right subtree
    else if (cmp > 0)
        tree->right = deleteNode(tree->right, key);

    // if key is same as tree's key,
    // then This is the node
    // to be deleted
    else
    {
        struct node *result;
        // node with only one child or no child
        if (tree->left == NULL)
        {
            result = tree->right;
        }
        else if (tree->right == NULL)
        {
            result = tree->left;
        }
        else
        {
            // node with two children:
            // Get the inorder successor
            // (smallest in the right subtree)
            struct node **successor = &(tree->right);
            while ((*successor)->left != NULL)
            {
                successor = &(*successor)->left;
            }
            // rotate pointers:
            result = *successor;
            result->left = tree->left;
            *successor = result->right;
            result->right = tree->right;
        }
        free(tree->key);
        free(tree);
        return result;
    }
    return tree;
}

I did not test it. Not successor being an alias of first a right and then of left fields.

  • Related