C语言中SLL的Delete(node)的正确语法是什么?

时间:2018-08-03 14:37:33

标签: c pointers singly-linked-list

假设相关的头文件,声明了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)如果我将void Delete (node **head)替换为node会发生什么? *Delete(node *head)

3)是否有另一种方法可以删除C中的节点?

预先感谢

2 个答案:

答案 0 :(得分:2)

这不是教程网站,但是这里...

您知道C中的参数是通过值传递 的吗?表示该值为已复制

例如:

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函数需要修改head points, we pass a pointer to头的位置,即指向该指针的指针:

Delete(&head);

Delete函数当然必须接受该类型,即指向node的指针的指针,即node **。然后,它使用解引用运算符*来获取指针指向的位置:

*head = temp->next;

答案 1 :(得分:1)

1)如果将node** head替换为node* head,则不会修改原始的head指针。您可能在某个head位置标记了链接列表的开始。删除节点时,有可能要删除head。在这种情况下,您需要修改head以指向链接列表中的下一个node

         *head = temp->next;
          free(temp);

这部分代码正是这样做的。在这里,temp == head。我们希望head指向head->next,但是如果我们将node* head传递给函数,则指针将被修改,但更改将消失,因为您正在按值传递指针。如果您想使更改反映在函数外部,则需要传递&head类型的node ** head

2)然后,您将更改函数定义以返回一个空指针(这是一个可以转换为任何指针的占位符指针。请注意不要破坏任何别名规则。但是(1)中的问题仍然存在,尽管如此,您可以返回修改后的head并将其分配给返回的值,在这种情况下,定义该函数与其他不需要修改head的情况不太适合,因此您可以返回一个指针如果已修改则返回head,否则返回NULL。尽管如此,这还是做些杂乱的方法。

3)是,但这取决于实现链表的方式。对于此处显示的数据类型,基本删除操作已给出。