【问题标题】:Deleting Node from Singly Linked List C [duplicate]从单链表 C 中删除节点
【发布时间】:2021-02-21 08:08:31
【问题描述】:

我正在检查单链表长度的奇偶校验:

  • 如果很奇怪,我必须删除第一个节点;
  • 如果是偶数,我必须删除最后一个节点。

我能够找出奇偶校验但无法删除相关节点。

鉴于我还必须使用签名void sil(struct node **head),我应该更改什么并添加到我的代码中?

// C program to check length
// of a given linklist 
#include<stdio.h> 
#include<stdlib.h>

// Defining structure 
struct Node 
{ 
    int data; 
    struct Node* next; 
}; 
  
// Function to check the length of linklist 
int LinkedListLength(struct Node* head) 
{ 
    while (head && head->next) 
    { 
        head = head->next->next; 
    } 
    if (!head) 
        return 0; 
    return 1; 
} 
      
// Push function 
void push(struct Node** head, int info) 
{ 
    // Allocating node 
    struct Node* node = (struct Node*) malloc(sizeof(struct Node)); 
      
    // Info into node 
    node->data = info; 
      
    // Next of new node to head 
    node->next = (*head); 
  
    // head points to new node 
    (*head) = node; 
} 
  
// Driver function 
int main(void) 
{ 
    struct Node* head = NULL; 
      
    // Adding elements to Linked List 
    push(&head, 4); 
    push(&head, 5); 
    push(&head, 7); 
    push(&head, 2); 
    push(&head, 9); 
    push(&head, 6); 
    push(&head, 1); 
    push(&head, 2); 
    push(&head, 0); 
    push(&head, 5); 
    push(&head, 5);
    int check = LinkedListLength(head); 
      
    // Checking for length of 
    // linklist 
    if(check == 0) 
    { 
        printf("Even\n"); 
    } 
    else
    { 
        printf("Odd\n"); 
    } 

   return 0; 
} 

【问题讨论】:

标签: c list


【解决方案1】:
typedef struct Node Node;

您可以使用一个简单的函数相对轻松地做到这一点,该函数将列表的地址和奇偶校验值作为参数,例如

/** delete 1st or last node from list given parity, 
 *  parity odd, delete 1st node, otherwise delete last
 */
void del_first_last_node (Node **head, int parity)
{
    Node **ppn = head;          /* pointer to pointer */
    Node *pn = *head;           /* pointer to node */

    if (parity & 1) {           /* is parity odd delete first node */
        *ppn = pn->next;        /* set node at current address to next */
        free (pn);
        return;
    }
    
    for (; pn; ppn = &pn->next, pn = pn->next) {    /* loop to end */
        if (pn->next == NULL) { /* if next pointer NULL */
            *ppn = pn->next;    /* set node at current address to next */
            free (pn);
            break;
        }
    }
}

上面,奇偶校验被检查为奇数,如果是,第一个节点被删除(并正确释放)。如果奇偶校验为偶数,则循环到列表末尾并删除最后一个节点(再次释放已删除的节点)

使用节点的地址和指向节点的指针进行迭代意味着不需要跟踪先前的节点或任何特殊情况。您只需将当前地址的节点替换为列表中的下一个节点。在第一个节点的情况下,您只需将当前head 地址处的节点替换为下一个节点(并且由于您还维护一个指向未更改节点的指针,您可以使用它来释放原始节点)对于最后一个节点,您只是将其内容替换为NULL。见Linus on Understanding Pointers

【讨论】:

    【解决方案2】:

    删除节点背后的想法大致相同:

    1. 创建指向要在结构中删除的节点的临时节点。

    2. 如果要删除头部,可以先用临时节点指向头部,然后将头部设置为指向它旁边的项目。它应该看起来像这样:node-&gt;head = node-&gt;head-&gt;next; 然后当然释放你的临时指针。

    3. 如果要删除尾部,有几种情况需要覆盖。如果您不使用 sentinel node ,则必须以不会破坏或破坏原始列表的方式遍历您的列表。其代码应如下所示:

      int deleteTail(list_t* list){
      
         int toReturn;
         //declare a temp pointer to the head of your list
         node_t* temp = list->head;
         //here you found the last node and have it in a temp pointer.
         while(temp->next != NULL) temp=temp->next;
         //get the value you want to return
         toReturn = temp->data;
         //free the last element
         free(temp);
         return toReturn;
      
      }
      

    【讨论】:

      【解决方案3】:

      “我正在检查单链表是奇数还是偶数。如果是奇数,我必须删除第一个节点,如果是偶数,我必须删除最后一个节点。 我做了我发现它奇怪或偶数的部分。但我不能删除节点。如果您能提供帮助,我将非常高兴。 另外我必须使用这个参数“void sil(struct node **head)”我应该改变什么并添加到我的代码中?”

          #include<stdio.h> 
          #include<stdlib.h>
          
          struct node{ 
              int data; 
              struct node *next; 
          }; 
      
          void push(struct node** head, int info) { 
              struct node *newN = (struct node *) malloc(sizeof(struct node)); 
                
              newN->data = info; 
              newN->next = *head; 
      
              *head= newN; 
          } 
          
          void sil(struct node **head){
                 if (*head==NULL) return;
      
                 struct node *ptail=NULL;
                 struct node *tail=*head;
                 int i;
      
                 for (i=1; tail->next!=NULL; ptail=tail, i++, tail=tail->next);
      
                 if (i%2){
                      tail=*head;
                      *head=(*head)->next;
                 }else{
                      ptail->next=NULL;
                 }
      
                 free(tail);
          }
      
          int main(void){ 
              struct node *head = NULL; 
               
              push(&head, 4); 
              push(&head, 5); 
              push(&head, 7); 
              push(&head, 2); 
              push(&head, 9); 
              push(&head, 6); 
              push(&head, 1); 
              push(&head, 2); 
              push(&head, 0); 
              push(&head, 5); 
              push(&head, 5);
      
              sil(&head);
      
             return 0; 
          } 
      

      试试看。

      【讨论】:

      • 谢谢!但是这个代码不起作用。代码没有输出。
      • 放输出。我刚刚写了删除功能。当您说输出时,您是指 printList 函数吗?
      • 不,我想说的是,当我尝试运行它没有运行的代码时。它说有很多错误
      • 现在试一试,告诉我它是否有效。
      • 非常感谢。你救了我。终于成功了!!
      猜你喜欢
      • 2017-10-21
      • 2013-08-30
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 2020-02-04
      相关资源
      最近更新 更多