Search code examples
crecursioncs50trie

Can this recursive function work without the `trav` pointer


I was working on a pset4 speller using tries. This function gives the size of a dictionary loaded as a trie. Can this function work without using the trav pointer which I am using? Do I have to point to the previous location or is this unnecessary?

Will my location be remembered in a function call and every time I recursively call a function the pointer to sizer will only be something specific to that call? And once I return the control back to the previous function, will it run on the previous location before I called the recursive function OR do I have to point it specifically to the previous location?

unsigned int size(void)
{    
    node *trav = root;
    int ctr = 0;
    for (int i = 0; i < N; i++)
    {       
            //Sizer is also a node pointer initialized to root globally
            if (sizer -> children[i] == NULL)
            {
                continue;

            }
            else
            {   
                //Store the current value of sizer 
                trav = sizer;

                //Change sizer to point to its child
                sizer = sizer -> children[i];

                if ((sizer -> is_word) == true)
                {
                    ctr ++;
                }
                // recursively call size again
                int x = size();
                ctr += x;

                /*After adding the number all the words IN THE CHILDREN
                  of this particular child, I want to point to the 
                  original `sizer`, so that i can move on to the next 
                  child and repeat the same for its chidren. To do that 
                  i need something to point back to original position
                */
                sizer = trav;

            }

    }

    return ctr;

Solution

  • Can this function work without using the trav pointer which i am using .

    Well... no, not this function. The problem here is that sizer is global so when you want the code to change it and later restore it, you will need an extra variable to store the value before its changed.

    However, why use a global variable?

    If you pass the pointer to the "current root", you can avoid trav and you get a more clean design without global variables.

    Something like:

    unsigned int size(node *sizer)
    {    
        unsigned int ctr = 0;       // notice: changed to unsigned to match the return type
        for (int i = 0; i < N; i++)
        {       
            if (sizer -> children[i] != NULL)
            {
                if ((sizer->children[i]->is_word) == true)
                {
                    ctr ++;
                }
                // recursively call size again while passing sizer->children[i]
                ctr += size(sizer->children[i]);
            }
        }
    
        return ctr;
    }
    

    Now every recursive call has its own sizer variable so you never need to change sizer and consequently you don't need to store into a travvariable.