开发者

C++ question regarding classes and default values for function arguments and recursion

开发者 https://www.devze.com 2023-04-07 22:51 出处:网络
I need to use recursion to count the nodes in a linked list. unsigned CLL::CountNodes(CNode* val) { if(!val)

I need to use recursion to count the nodes in a linked list.

unsigned CLL::CountNodes(CNode* val)
{
    if(!val)
        return 0;
    else
        return 1 + CountNodes(val->next);
}

So when I want to count the nodes in the linked list, from say, another function, I go:

int main()
{
    CLL list();
    cout << list.CountNodes(list.head);
}

This seems a bit dodgy though, because the class should be able to count the list without me passing in a point to the head of the head of the list. This seems straight forward with a for-loop; however, with recursion, I tried:

unsigned CLL::CountNodes(CNode* val = head)
{
    if(!val)
        return 0;
    else
        return 1 + CountNodes(val->next);
}

but this did not work because head is not static. Then making head static is a problem, because I have to declare it outside the class.

Is there anyway to solve the problem? e.g. cout << list.CountNodes(); Or must the head of the list always be passe开发者_运维百科d in when using recursion?


In C++ there is always a way. You may have two overloaded functions, for example:

unsigned CountNodes (CNode* val)
{
    return val ? CountNodes(val->next) + 1 : 0;
}

unsigned CountNodes ()
{
    return CountNodes (head);
}

I would also recommend making unsigned CountNodes (CNode* val) function static since it doesn't need anything from CLL class, and unsigned CountNodes () method constant because it doesn't change object's state.

And by the way, there is a ternary operator in C++ that makes life easier, code more readable and may even make it faster. So instead of:

if(!val)
        return 0;
    else
        return 1 + CountNodes(val->next);

... you could write like:

return val ? 1 + CountNodes(val->next) : 0;


You could have a public function int CountNodes() that calls a private int CountNodes(CNode*) method with this->head.

// in class CLL
public:
    unsigned int CountNodes()
    {
        return CountNodes(head);
    }

private:
    CNode* head;
    unsigned int CountNodes(CNode* val)
    {
        if(!val)
            return 0;
        else
            return 1 + CountNodes(val->next);
    }

Now you have better encapsulation has your head data member is private and your client code can be made simpler.

int main()
{
    CLL list();
    cout << list.CountNodes();
}


Use 2 functions. The first one as written, plus one with no arguments which calls the first with 'head' as the argument.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号