【问题标题】:Delete list of Singly linked list删除单链表列表
【发布时间】:2017-08-20 20:13:44
【问题描述】:

我正在练习数据结构,我已经实现了一个创建单链表、添加到列表和删除列表的代码。我真的很想知道我的删除列表功能是否真的在做它应该做的事情。我认为这是因为当我尝试在删除后打印列表时它崩溃了。因此,有关确保它删除我的列表的任何建议或您可能对改进我的代码有任何其他建议。在动态分配内存方面,我还是个新手。

typedef struct node {
    int data;
    node* next;
}* nodePtr;

nodePtr addToList(nodePtr head, int data) {
    nodePtr newItem = new node; //create a new item 

    newItem->data = data; //assign the data to the new item 
    newItem->next = head; //point to head

    return newItem; //return the new head
}

void deleteList(nodePtr head) {
    if (head == nullptr) {
        return;
    }
    else {
        deleteList(head->next);
        delete head;
        head = nullptr;
    }
}

void Print(nodePtr n) {
    while (n != nullptr) {
        cout << n->data << " ";
        n = n->next;
    }
}

int main() {
    nodePtr head = new node;
    nodePtr second = new node;
    nodePtr third = new node;

    head->data = 1;
    head->next = second;

    second->data = 2;
    second->next = third;

    third->data = 3;
    third->next = nullptr;

    Print(head);
    cout << endl;

    head = addToList(head, 0);

    Print(head);
    cout << endl;

    deleteList(head);

    return 0;
}

【问题讨论】:

  • 我建议您使用调试器逐行检查代码以查找并解决问题。
  • 你的 addToList 没有做它应该做的事情。尝试在不调用 addToList 函数的情况下调用 delete 并从那里修复。在您的主目录中,您没有使用 addToList 而是手动创建列表。
  • 要确定您是否正确清理分配的内容,您可以尝试使用 valgrind 之类的工具。

标签: c++ singly-linked-list


【解决方案1】:

当你打电话时:

deleteList(head);

head 在该语句之后将不等于NULL。相反,您需要执行以下操作:

deleteList(head);
head = NULL;

或:

void deleteList(nodePtr & head) {
    if (head == nullptr) {
        return;
    }
    else {
        deleteList(head->next);
        delete head;
        head = nullptr;
    }
}

请注意,我们使用 deleteList 的引用参数。

【讨论】:

    【解决方案2】:

    除了比尔的回答中指出的一个小警告之外,您的功能大部分是正确的。

    我只是想指出,您实际上并不需要递归来删除列表。这是另一种方法。

    while(head != nullptr) {
        node *deleteMe = head;
        head = head->next;
        delete deleteMe;
    }
    

    【讨论】:

      【解决方案3】:

      我会添加这样的东西来清理代码:

      nodePtr create_node(int n) {
         nodePtr p = new node;
         assert (p != NULL);
         p -> data = n;
         p -> next = NULL;
      }
      

      这样,您可以使用如下循环清理您的主要功能以进行测试:

      for (int i = 0; i < 10; ++i) {
         nodePtr p = create_node(i);
         head = addToList(head, p);
      }
      

      然后通过引用传递你的头指针,所以你最终会得到这样的东西:

      nodePtr addToList(nodePtr&head, nodePtr newItem) {
          newItem->next = head; //point to head
          head = newItem;
      }
      

      这些几乎只是样式更改,但它可以更轻松地测试程序,而不是在主函数中单独创建节点,并且它使代码看起来更简洁。您可以做的另一件事是尝试首先迭代地删除此列表,一旦您实现递归删除可能更有意义。

      要实际调试它并检查您是否正确地释放内存,最好的方法是使用调试器,您可以添加 assert( ) 来验证空值,但值得检查 gdb 之类的东西(用于命令行) : https://www.cs.cmu.edu/~gilpin/tutorial/。该教程实际上是用于调试链表的内存分配,因此可能会有所帮助。

      【讨论】:

        猜你喜欢
        • 2017-05-19
        • 1970-01-01
        • 2020-08-11
        • 2016-07-30
        • 2012-09-11
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 2013-11-22
        相关资源
        最近更新 更多