我有以下功能,用于从指定位置的链表中删除节点:
void deleteNodeAt(node *head, int pos) {
if(head==NULL)
return;
node *temp=malloc(sizeof(node));
int index=0;
while(head!=NULL) {
if(index==pos-1)
temp=head;
if(index==pos) {
temp->next=head->next;
head=head->next;
free(temp);
temp=NULL;
}
else
head=head->next;
index++;
}
}
如果我不尝试释放temp节点或将其设置为NULL,它会正常工作,但调用free(temp(会破坏函数。我不明白我做错了什么。
首先,我不明白为什么要在应该释放节点的代码中执行malloc
。
此外,您正在释放错误的节点。您想要释放的节点是head
,它是而不是temp
。
试试看:
void deleteNodeAt(node *head, int pos)
{
if(head==NULL)
return;
node *temp;
int index=0;
while(head!=NULL)
{
if(index==pos-1)
temp=head;
if(index==pos)
{
temp->next=head->next;
free(head);
// Done - the node has been free'd so just return
return;
}
head=head->next;
index++;
}
}
然而,仍然存在一个问题。
考虑一下:
当pos为零时(即,当您尝试删除当前
head
时(会发生什么
答案:您将使用未初始化的temp
。太糟糕了。此外,呼叫者将如何知道head
已更改?您需要一些额外的代码来处理这种情况。
假设列表头的pos从0开始,则需要将指针传递给head才能删除pos 0。调用之后,头将发生更改,因此指向列表的任何其他指针都将无效。
#define START_OF_LIST 0
void deleteNodeAt(node **phead, int pos)
{
if (pos < START_OF_LIST || !*phead)
return; /* bad pos or empty list, always check input */
node *prev = *phead;
if (pos == START_OF_LIST) {
/* special case - delete head of list */
*phead = (*phead)->next;
free(prev);
return;
}
while (1) {
node * temp = prev->next;
if (!temp) /* Not enough elements in list */
return;
pos--;
if(pos == START_OF_LIST) {
prev->next = temp->next; /* unlink temp */
free(temp);
return;
}
prev = temp; /* On to the next! */
}
}