Вопрос C ++ относительно классов и значений по умолчанию для аргументов функций и рекурсии - PullRequest
1 голос
/ 28 сентября 2011

Мне нужно использовать рекурсию для подсчета узлов в связанном списке.

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

Поэтому, когда я хочу подсчитать узлы в связанном списке, скажем, из другой функции, я иду:

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

Это кажется немного хитрым, потому что класс должен быть в состоянии посчитать список без того, чтобы я указывал точку в начало заголовка списка.Это кажется прямым с циклом for;однако, с рекурсией я попытался:

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

, но это не сработало, потому что голова не статична.Тогда создание статической головы - проблема, потому что я должен объявить это вне класса.

Есть ли способ решить проблему?например, cout << list.CountNodes ();Или заголовок списка всегда должен передаваться при использовании рекурсии? </p>

Ответы [ 3 ]

1 голос
/ 28 сентября 2011

В C ++ всегда есть способ.У вас может быть две перегруженные функции , например:

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

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

Я бы также рекомендовал сделать unsigned CountNodes (CNode* val) функцию статической , так как ей ничего не нужно от CLL class и unsigned CountNodes () константа метода , поскольку она не изменяет состояние объекта.

И, кстати, в C ++ есть троичный оператор , которыйделает жизнь проще, код более читабельным и даже может сделать его быстрее.Таким образом, вместо:

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

... вы можете написать так:

return val ? 1 + CountNodes(val->next) : 0;
0 голосов
/ 28 сентября 2011

Используйте 2 функции.Первый, как написано, плюс один без аргументов, который вызывает первый с аргументом «голова».

0 голосов
/ 28 сентября 2011

Вы можете иметь публичную функцию int CountNodes(), которая вызывает приватный метод int CountNodes(CNode*) с 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);
    }

Теперь у вас есть лучшая инкапсуляция, если ваш элемент данных head является личным, а ваш клиентский код может быть упрощен.

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