如何编写可修改链表头指针的 C 函数?
原文:https://www.geeksforgeeks.org/how-to-write-functions-that-modify-the-head-pointer-of-a-linked-list/
考虑链表的简单表示(没有任何虚拟节点)。 在此类链表上运行的函数可以分为两类:
1)不修改头指针的函数:此类函数的示例包括:打印链表,更新节点的数据成员(如将给定值添加到所有节点)或其他一些节点数据的访问/更新操作。
通常很容易确定此类函数的原型。 我们总是可以将头指针作为参数传递并遍历/更新列表。 例如,以下函数将x
添加到所有节点的数据成员。
void addXtoList(struct Node *node, int x)
{
while(node != NULL)
{
node->data = node->data + x;
node = node->next;
}
}
2)修改头指针的函数:示例包括,在开头插入一个节点(此函数中始终修改头指针),在结尾插入一个节点(仅当第一个指针被修改时,才修改头指针)。 插入节点),删除给定的节点(当删除的节点是第一个节点时,将修改头指针)。 在这些函数中,可能有不同的方法来更新头指针。 让我们使用以下简单问题讨论这些方式:
“给出一个链表,编写一个函数deleteFirst()
来删除给定链表的第一个节点。 例如,如果列表是 1 -> 2 -> 3 -> 4
,则应将其修改为2 -> 3 -> 4
”
解决问题的算法是一个简单的 3 个步骤:(a)存储头指针(b)更改头指针以指向下一个节点(c)删除前一个头节点。
以下是在deleteFirst()
中更新头指针的不同方法,以便可以在任何地方更新列表。
2.1)将头指针设为全局:我们可以将头指针设为全局,以便可以在我们的函数中对其进行访问和更新。 以下是使用全局头指针的 C 代码。
// global head pointer
struct Node *head = NULL;
// function to delete first node: uses approach 2.1
// See http://ideone.com/ClfQB for complete program and output
void deleteFirst()
{
if(head != NULL)
{
// store the old value of head pointer
struct Node *temp = head;
// Change head pointer to point to next node
head = head->next;
// delete memory allocated for the previous head node
free(temp);
}
}
有关使用上述函数的完整运行程序,请参见这里。
不建议使用这种方法,因为它存在许多类似以下的问题:
a)head
可以全局访问,因此可以在项目中的任何位置进行修改,并可能导致无法预测的结果。
b)如果存在多个链表,则需要多个具有不同名称的全局头指针。
请参见这里,以了解为什么我们应避免在项目中使用全局变量的所有原因。
2.2)返回头指针:我们可以以这样的方式编写deleteFirst()
:它返回修改后的头指针。 谁在使用此函数,都必须使用返回的值来更新头节点。
// function to delete first node: uses approach 2.2
// See http://ideone.com/P5oLe for complete program and output
struct Node *deleteFirst(struct Node *head)
{
if(head != NULL)
{
// store the old value of head pointer
struct Node *temp = head;
// Change head pointer to point to next node
head = head->next;
// delete memory allocated for the previous head node
free(temp);
}
return head;
}
有关完整的程序和输出,请参见此的[。
这种方法比以前的方法好得多。只有一个问题,如果用户错过了将返回值分配给head
的事情,事情就会变得混乱。 C/C++ 编译器允许在不分配返回值的情况下调用函数。
head = deleteFirst(head); // proper use of deleteFirst()
deleteFirst(head); // improper use of deleteFirst(), allowed by compiler
2.3)使用双指针:此方法遵循简单的 C 规则:如果要在另一个函数内修改一个函数的局部变量,请传递指向该变量的指针。 因此,我们可以将指针传递到头指针,以在deleteFirst()
函数中修改头指针。
// function to delete first node: uses approach 2.3
// See http://ideone.com/9GwTb for complete program and output
void deleteFirst(struct Node **head_ref)
{
if(*head_ref != NULL)
{
// store the old value of pointer to head pointer
struct Node *temp = *head_ref;
// Change head pointer to point to next node
*head_ref = (*head_ref)->next;
// delete memory allocated for the previous head node
free(temp);
}
}
有关完整的程序和输出,请参见此的[。
这种方法似乎是这三种方法中最好的,因为出现问题的机会更少。](http://ideone.com/9GwTb)
如果发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。
版权属于:月萌API www.moonapi.com,转载请注明出处