删除单链表

时间:2017-08-20 20:13:45

标签: c++ singly-linked-list

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

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;
}

3 个答案:

答案 0 :(得分:2)

致电时:

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的引用参数。

答案 1 :(得分:1)

除了Bill的回答中指出的一个小警告之外,你的功能大多是正确的。

我只是想指出你真的不需要递归来删除列表。这是另一种方式。

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

答案 2 :(得分:1)

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

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/。该教程实际上是用于调试链表的内存分配,因此它可能会有所帮助。