这是我的删除代码。问题是,当我从尾部或第n个节点删除某些东西时,它工作得非常好,但每当我从头部中删除某些内容时,它就会崩溃。我应该做些什么来避免崩溃?
->all()
}
答案 0 :(得分:1)
如果要删除的节点是头节点,则会发生以下情况:
您声明Node *prev
。请注意,它是未初始化的。然后输入do while
循环,但在第一个if条件处中断,因为tmp->Data() == data
。所以你退出do while循环而不执行下一个语句,这将初始化prev
。现在不在循环中,下一个语句访问SetNext
的{{1}}字段,而之前的语句是单元化的。这是未定义的行为,任何事情都可能发生;崩溃是一件事。
避免这种情况的方法是添加一个检查,以确定prev
是否已被酉化,或者是&t; tmp'是头节点。在这种情况下,您应该删除头部,并在头部之后返回节点。由于您的函数具有prev
签名,因此您应该删除头节点,并使头指针在头后引用该节点。
答案 1 :(得分:0)
此代码存在多个问题。
if ( tmp->Next() == NULL )
此检查并不意味着“列表的最后一个节点”实际意味着列表中只有一个节点,因为以下代码仅在至少存在的情况下运行这里需要处理这种情况的两个节点。tmp->Data() == data
检查以确保列表中的唯一节点也是我们要删除之前要删除的节点。Node *prev = NULL;
此指针应初始化,以便我们稍后检查NULL
以查看它是否是需要删除的头部。if ( tmp->Data() == data )
之前在break;
的循环检查中完成所有删除,否则你将无法知道循环是自然结束还是被破坏,以决定是否是否找到了节点。以下是更正后的代码:
void List::Delete(int data) {
// Create a temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// it is the only node in the list
if ( tmp->Next() == NULL && tmp->Data() == data ) {
delete tmp;
head = NULL;
}
else {
// Parse through the nodes
Node *prev = NULL;
do {
if ( tmp->Data() == data ){
if( prev == NULL ) // this is the head case
head = head->Next();
else // Adjust the pointers
prev->SetNext(tmp->Next());
// Delete the current node
delete tmp;
break;
}
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
}
}
注意:尾部工作正常,代码中没有任何更改,因为此案例创建的唯一区别是tmp->Next()
对于该情况{@ 1}}这正是我们想要NULL
中的新尾部,即将prev->SetNext(tmp->Next());
设置为Next
。