C 中 SLL 的 Delete(node ) 的正确语法是什么?
What is the correct syntax of Delete(node ) for SLL in C?
假设相关的头文件,声明了C中单链表的函数。
Delete() 的以下定义是否正确?
/* The Structure for SLL
typedef struct SLL
{
int data;
struct SLL *next;
}node;
Function Delete() deletes a node*/
void Delete( node **head)
{
node *temp, *prev;
int key;
temp = *head;
if(temp == NULL)
{
printf("\nThe list is empty");
return;
}
clrscr();
printf("\nEnter the element you want to delete:");
scanf("%d", &key);
temp = search( *head , key);//search()returns the node which has key
if(temp != NULL)
{
prev = get_prev(*head, key);
if(prev != NULL)
{
prev->next = temp->next;
free(temp);
}
else
{
*head = temp->next;
free(temp);
}
printf("\nThe node is deleted");
getch();
}
}
1) 如果我用 (node *head)
替换 (node ** head)
会怎样?
2) 如果我用 node 替换 void Delete (node **head)
会发生什么
*Delete(node *head)
?
3) 在 C 中是否有其他方法来删除节点?
提前致谢
1) 如果将 node** head
替换为 node* head
,则不会修改原始 head
指针。您可能在某个地方有一个 head
标记链表的开头。当你删除一个节点时,有可能你想删除head
。在这种情况下,您需要修改 head
以指向链表中的下一个 node
。
*head = temp->next;
free(temp);
您的这部分代码正是这样做的。这里,temp == head
。我们希望 head
指向 head->next
,但是如果我们将 node* head
传递给函数,指针将被修改,但更改将消失,因为您是按值传递指针。如果您希望更改反映在函数外部,则需要传入类型为 node ** head
的 &head
。
2) 然后将函数定义更改为 return 空指针(这是一个可以转换为任何指针的占位符指针。注意不要破坏任何别名规则。但是(1) 中的问题仍然存在,但是,您可以 return 修改后的头部,并将其分配给 returned 值。在这种情况下,定义函数将不适合头部的其他情况不需要修改。所以你可以 return head 的指针,如果它被修改,或者 return NULL 当它没有被修改时。不过,恕我直言,这是一种稍微混乱的做事方法。
3) 是的,但这取决于链表的实现方式。对于此处显示的数据类型,基本删除操作已给出。
这不是一个教程站点,但这里是...
您知道 C 中的参数是按值 传递的吗?表示该值是 copied.
例如:
void some_function(int a)
{
// ...
}
调用上面的函数时,如
int x = 5;
some_function(x);
然后x
中的值被复制到函数中的参数a
中。如果函数内的代码赋值给 a
(例如 a = 12;
),那么您只需修改局部变量 a
,即副本。它不修改原始变量。
现在,如果我们想要修改x
的函数,那么我们必须模仿通过引用传递,即使用指针和地址运算符完成:
void some_function(int *a)
{
*a = 12; // Modify where a is pointing
}
现在调用它,我们不创建指针变量并传递它(尽管这也是可能的),而是使用寻址运算符 &
传递指向变量的指针:
int x = 5;
some_function(&x); // Pass a pointer to the variable x
指针 &x
将按值传递 (因为这是在 C 中传递参数的唯一方法),但我们不想修改指针,我们要修改数据指向的地方。
现在回到你的具体函数:你的函数要修改一个指针变量,那么我们如何模拟引用传递?通过将指针传递给指针。
所以如果你有
node *head;
// Initialize head, make it point somewhere, etc.
现在由于 Delete
函数需要修改 where head points, we pass a pointer to
head`,指向指针的指针:
Delete(&head);
Delete
函数当然必须接受那个类型,一个指向node
的指针,即node **
。然后它使用取消引用运算符 *
来获取指针指向的位置:
*head = temp->next;
假设相关的头文件,声明了C中单链表的函数。
Delete() 的以下定义是否正确?
/* The Structure for SLL
typedef struct SLL
{
int data;
struct SLL *next;
}node;
Function Delete() deletes a node*/
void Delete( node **head)
{
node *temp, *prev;
int key;
temp = *head;
if(temp == NULL)
{
printf("\nThe list is empty");
return;
}
clrscr();
printf("\nEnter the element you want to delete:");
scanf("%d", &key);
temp = search( *head , key);//search()returns the node which has key
if(temp != NULL)
{
prev = get_prev(*head, key);
if(prev != NULL)
{
prev->next = temp->next;
free(temp);
}
else
{
*head = temp->next;
free(temp);
}
printf("\nThe node is deleted");
getch();
}
}
1) 如果我用 (node *head)
替换 (node ** head)
会怎样?
2) 如果我用 node 替换 void Delete (node **head)
会发生什么
*Delete(node *head)
?
3) 在 C 中是否有其他方法来删除节点?
提前致谢
1) 如果将 node** head
替换为 node* head
,则不会修改原始 head
指针。您可能在某个地方有一个 head
标记链表的开头。当你删除一个节点时,有可能你想删除head
。在这种情况下,您需要修改 head
以指向链表中的下一个 node
。
*head = temp->next;
free(temp);
您的这部分代码正是这样做的。这里,temp == head
。我们希望 head
指向 head->next
,但是如果我们将 node* head
传递给函数,指针将被修改,但更改将消失,因为您是按值传递指针。如果您希望更改反映在函数外部,则需要传入类型为 node ** head
的 &head
。
2) 然后将函数定义更改为 return 空指针(这是一个可以转换为任何指针的占位符指针。注意不要破坏任何别名规则。但是(1) 中的问题仍然存在,但是,您可以 return 修改后的头部,并将其分配给 returned 值。在这种情况下,定义函数将不适合头部的其他情况不需要修改。所以你可以 return head 的指针,如果它被修改,或者 return NULL 当它没有被修改时。不过,恕我直言,这是一种稍微混乱的做事方法。
3) 是的,但这取决于链表的实现方式。对于此处显示的数据类型,基本删除操作已给出。
这不是一个教程站点,但这里是...
您知道 C 中的参数是按值 传递的吗?表示该值是 copied.
例如:
void some_function(int a)
{
// ...
}
调用上面的函数时,如
int x = 5;
some_function(x);
然后x
中的值被复制到函数中的参数a
中。如果函数内的代码赋值给 a
(例如 a = 12;
),那么您只需修改局部变量 a
,即副本。它不修改原始变量。
现在,如果我们想要修改x
的函数,那么我们必须模仿通过引用传递,即使用指针和地址运算符完成:
void some_function(int *a)
{
*a = 12; // Modify where a is pointing
}
现在调用它,我们不创建指针变量并传递它(尽管这也是可能的),而是使用寻址运算符 &
传递指向变量的指针:
int x = 5;
some_function(&x); // Pass a pointer to the variable x
指针 &x
将按值传递 (因为这是在 C 中传递参数的唯一方法),但我们不想修改指针,我们要修改数据指向的地方。
现在回到你的具体函数:你的函数要修改一个指针变量,那么我们如何模拟引用传递?通过将指针传递给指针。
所以如果你有
node *head;
// Initialize head, make it point somewhere, etc.
现在由于 Delete
函数需要修改 where head points, we pass a pointer to
head`,指向指针的指针:
Delete(&head);
Delete
函数当然必须接受那个类型,一个指向node
的指针,即node **
。然后它使用取消引用运算符 *
来获取指针指向的位置:
*head = temp->next;