我无法从链接列表中删除最后一个元素,问题是当我删除它时,唯一的节点我是前一个节点(在最后一个节点之前)。这是我的代码:
node *remove_node(int d, node *lst){
node *prev;
node *temp = lst;
if(temp->data == d){
if(temp->next != NULL){
node *sec_temp = temp;
temp = temp->next;
free(sec_temp);
return temp;
}
else{
free(temp);
return NULL;
}
}
while(temp != NULL && temp->data != d){
prev = temp;
temp = temp->next;
}
if(temp == NULL){return lst;}
//Here is the problem
if(temp->next == NULL){
prev->next = NULL;
free(temp);
return prev;
}
//end
else {
prev->next = temp->next;
free(temp);
return prev;
}
}
int main(){
node *lst = NULL;
lst = new_node(1, lst);
lst = new_node(2, lst);
lst = new_node(3, lst);
lst = new_node(4, lst);
lst = remove_node(1, lst);
print(lst);// this will print the list, works perfect
return 0;
}
当我删除1(这是列表中的最后一个元素)时,只打印了2,在其他情况下,一切都很完美(如果我删除2或3或4,我就不会有任何问题。 )。 有什么想法可以解决问题吗?
答案 0 :(得分:0)
你让它变得比它需要的复杂得多。有几种方法可以删除前向链接的,以空值终止的链表中的节点。您可以使用两个指针(前一个和当前指针)来执行此操作,这就是您尝试使用的指针。在您理解实际算法之前停止编码:
node *remove_node(int d, node *lst)
{
node *prev = NULL, *cur = lst;
while (cur && cur->data != d)
{
prev = cur;
cur = cur->next;
}
if (cur)
{
if (!prev) // head node was the match
lst = lst->next;
else
prev->next = cur->next;
free(cur);
}
return lst;
}
如何运作
最初我们有两个指针,prev
指向列表中的前一个节点,指向当前测试节点,最初为NULL,cur
,我们正在测试的当前节点,最初是名单头。
一次一个节点地运行列表,每次测试我们是否(a)尚未到达列表末尾(cur != NULL
)和(b)找到与我们的目标数据匹配的节点({ {1}})。我们相应地打破了循环。一旦循环中断,cur->data == d
要么指的是要删除的节点,要么是NULL,这意味着我们找不到匹配项。
cur
的值仅在prev
非NULL时才重要,这意味着我们找到了匹配项。如果我们找到匹配项并且cur
我们必须位于头节点上,否则prev == NULL
指的是prev
指针需要链接的节点到next
指针拼接列表并在删除之前删除我们的受害者。
真的就是这一切。我强烈建议您通过调试器手动执行删除操作,并查看指针在此过程中的地址。调试器不仅仅是为了找到破碎的东西。它们是帮助更好地理解代码如何工作的一个很好的工具(因为你实际上可以实现"看到"它工作)。
祝你好运。
答案 1 :(得分:0)
问题是你返回prev
指针,该指针指向被移除的元素之前的元素,但是列表的开头实际上仍然是lst
指针。接下来在main
方法中,您在打印方法中使用返回的指针,因此您只打印最后一个元素。