如何处理成员函数中的递归?

问题描述 投票:1回答:3

例如,我有empty函数来清除链接列表:

void empty(Node* head) {
        if (head->next) { empty(head->next); }
        delete head;
        head = nullptr;
    }

但是后来我为链表创建了一个类,所以现在我不需要传递head参数:

void empty() {
        if (head->next) { empty(head->next); }
        delete head;
        head = nullptr;
    }

但是empty(head->next)行显然是错误的,因为empty不接受任何参数。我想到这个想法是在一个函数(带有lambda)中创建一个函数,类似这样:

void empty() {
        std::function<void(Node*)> emptyWrapper = [&] (Node* l_head) {
            if (l_head->next) { emptyWrapper(l_head->next); }
            delete l_head;
            l_head = nullptr;
        };
        emptyWrapper(head);
    }

但是我想知道是否还有更好的方法可以做到。 Lambdas最近成为我的理想选择。

c++ class recursion singly-linked-list function-definition
3个回答
1
投票

注意:正如其他人所提到的,您无需在此处使用递归。此示例假定您出于某种原因想要或没有提到。这是您使用递归进行[[would的方式。但是,从长远来看,应该使用循环进行重组。


您可以创建列表的公开和私有版本:

class list { public: void empty(); //... private: void empty(Node* head); // alternatively, you could make this static instead: static void empty(Node* head); //... }

然后您可以调用从另一个empty()内部获取参数的empty()

void list::empty() { if(this->head) { // check here so ->next won't fail in the helper function. // maybe you should add a check there instead empty(this->head); } }


P.S。您可能不应该像在这里一样在整个地方使用名称head。这只是我一起提出的一个简单例子。但是至少您可以通过这种方式获得大致的想法。

1
投票
简单的解决方案是拥有一个辅助函数来完成递归函数正在执行的工作。

class List{ public: void empty(){ if (head) { empty_helper(head); } delete head; head = nullptr; } private: // should probably be static to avoid propagating this. void empty_helper(Node* head) { if (head->next) { empty_helper(head->next); } delete head; head = nullptr; } };

当然还有其他选项,例如使其不递归。

我认为在这种情况下,lambda是不必要的。


1
投票
一种通用方法是声明一个公共成员函数,然后依次调用一个私有静态递归成员函数。

请注意,名称empty听起来令人困惑。最好将函数命名为例如clear

您在这里

#include <functional> //... class List { public: //... void clear() { clear( head ); } private: static void clear( Node * &head ) { if ( head ) { delete std::exchange( head, head->next ); clear( head ); } } //... }

无需定义辅助静态函数就可以使用相同的方法。

void clear() { if ( head ) { delete std::exchange( head, head->next ); clear(); } }

这里是演示程序。

#include <iostream> #include <iomanip> #include <functional> template <typename T> class List { private: struct Node { T data; Node *next; } *head = nullptr; public: void push_front( const T &data ) { head = new Node { data, head }; } friend std::ostream & operator <<( std::ostream &os, const List &list ) { for ( Node *current = list.head; current; current = current->next ) { os << current->data << " -> "; } return os << "null"; } bool empty() const { return head== nullptr; } void clear() { if ( head ) { delete std::exchange( head, head->next ); clear(); } } }; int main() { List<int> list; const int N = 10; for ( int i = N; i != 0; ) { list.push_front( i-- ); } std::cout << list << '\n'; list.clear(); std::cout << "list is empty " << std::boolalpha << list.empty() << '\n'; return 0; }

程序输出为

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null list is empty true

© www.soinside.com 2019 - 2024. All rights reserved.