例如,有一个练习说:
编写一个函数,从链接列表中删除节点,只给出指针
这就是解决方案:
void deleteNode(Node* toDelete) {
// this function essensially first copies the data from the next pointer
// and then, deletes the next pointer
// However, it doesn't work if trying to delete the last element in the list
Node *temp = toDelete->next; // create a temp, assign to the one after toDelete
toDelete->data = temp->data; // change toDelete's data to the one's after it
toDelete->next = temp->next; // change toDelete's next to the one's after it
delete temp;
temp = nullptr;
}
如果仅指针最后一个节点,如何更改我的解决方案才能删除链接列表中的 last 元素?
答案 0 :(得分:8)
您可以做的是将一个标记节点添加到列表的末尾。您永远不会删除该节点,也绝不会使用它来存储数据。然后,您的解决方案将适用于所有数据节点。这不需要对节点结构进行任何更改,但需要更改迭代列表的方式。
答案 1 :(得分:3)
不,单链表无法实现。
原因是您需要修改倒数第二个节点(使其next
指针为空)。但是无法从最后一个节点找到该节点。
通常,只有指向节点的指针,才能从单链表中删除节点。
你目前所做的实际上是一个“作弊”,因为你并没有真正删除指向的节点。您正在改变列表,然后删除指向的节点的后继。当你调用这个函数时,如果其他地方的某些代码在某个地方持有一个指向该继承符的指针,那么这会产生影响 - 它们的指针无效。所以你要删除指向的数据元素,但是你没有删除指向的节点。
答案 2 :(得分:2)
为了处理单个链表中的节点删除,您需要在之前和之后修改节点。
+-----+ +----------+ +------+
header----->| |->| toDelete |->| |
+-----+ +----------+ +------+
你需要一个指向列表第一个元素的指针,否则由于数据结构的性质,你不可能做你想做的事。
首先在您需要删除的节点之前找到节点,例如
Node* before = header;
for (;before->next != toDelete; before = before->next) {;}
现在执行before->next = toDelete->next
如果toDelete
是最后一个节点,那么它将是一个nullptr,否则就是指向下一个节点的指针
(当然你需要删除toDelete
指向两种情况的内容)