使用递归函数删除链表?

时间:2014-03-12 04:34:59

标签: c++

struct Node {
    int value;
    Node* next;
    ~Node() {
        delete next;
    }
};

Node* deleteList(Node* p) {
    if(p == nullptr) return nullptr;
    Node* pNext = p->next;
    delete p;
    return deleteList(pNext);
}

编译器说了一些关于访问不良的信息。 我试图设置断点来调试它。如果链表是[3,2,1],它首先删除3,然后删除2和1,然后跳回到2,然后遇到异常。 有人能告诉我这是什么问题吗?

5 个答案:

答案 0 :(得分:3)

Node结构的析构函数已经在“next”上调用delete。因此,它转到“next”并调用它的析构函数,依此类推。然后,只需调用p(其中p是节点*)即可删除链接列表中delete p;后面的所有节点。

我建议你摆脱Node的析构函数,以防止发生链破坏。

struct Node {
    int value;
    Node* next;
};

作为旁注,虽然我不知道你的其余代码,但我没有看到为什么deleteList(Node * p)应该返回一个Node *的原因(因为它总是nullptr,没有意思结果返回)。

void deleteList(Node* p)
{
    if(p == nullptr) return;
    Node* pNext = p->next;
    delete p;
    deleteList(pNext);
}

答案 1 :(得分:2)

我会猜测您在已删除的实例上多次调用delete。当你调用delete p;时,p的析构函数被调用,它正在删除列表中的下一个节点。然后递归调用deleteList,向它传递刚刚被p的析构函数删除的节点,使你指向的指针无效。

您需要做的是确定Node是否拥有列表中跟随它的Node(即,是否负责清理它),或者某些外部代码是否需要注意那个。你不能两者兼顾。


编辑:

顺便说一句,你真正想要的不是有一个递归删除函数,而是一个deleteList函数中的循环。有点像...

struct Node {
  int value;
  Node* next;
};

// Loop in the function; recursion not required, and no return value.
void delete_list(Node* n)
{
  Node* tmp;
  while (nullptr != n) {
    tmp = n->next;
    delete n;
    n = tmp;
  }
}

在这种情况下,Node实例不拥有其兄弟Node(Node.next),并且不负责解除分配;这取决于delete_list函数。

答案 2 :(得分:2)

如果链接列表为:[3, 2, 1],则当您致电deleteList时,会发生以下情况:

    {li>

    p = 3pNext = 23delete p;删除然后调用了析构函数,因此delete next会删除2和递归1

  1. 然后在delete p函数deleteList之后,再次调用deleteList(pNext),所以这次:p = 2pNext = 1,因为{{1在上一步中已经删除了,当你再次调用2时它会损坏。

  2. 请删除delete p中的delete next;

    实际上我没有看到为什么应该使用~Node()的原因,因为它总会返回deleteList并删除所有节点。那么为什么不删除nullptr函数,并将deleteList保留在delete next;中。您可以直接删除创建的~Node()对象。

    当然,执行此任务的最佳方式是:Node

答案 3 :(得分:1)

delete next;的析构函数中删除行Node

答案 4 :(得分:0)

我认为你可能有两种选择。 首先,正如R Sahu所说,删除析构函数中的delete next

struct Node {
    int value;
    Node* next;
};

Node* deleteList(Node* p) {
    if(p == nullptr) return nullptr;
    Node* pNext = p->next;
    delete p;
    return deleteList(pNext);
}

第二,只需删除deleteList中链接的头节点,但不能递归删除节点。

struct Node {
    int value;
    Node* next;
    Node() : value(0), next(nullptr)
    {}
    ~Node() {
        if (next != nullptr)
        {
            delete next;
        }
    }
};

Node* deleteList(Node* p) {
    if (p != nullptr)
    {
        delete p;
    }
    return nullptr;  // in fact your code always return nullptr. so it just return nullptr here.
}