删除c中单链表中的节点

delete node(s) in a singly linked list in c

我创建了一个接受输入值的单向链表。我尝试从输入中删除某些节点,但代码未按预期执行。

这是我的代码

#include <stdio.h>
#include <stdlib.h>

struct NODE {
     int value;
     struct NODE *prev;
};

struct NODE* head = NULL;

void insert(int data) {
   
    struct NODE *p;
    p = malloc(sizeof(struct NODE));
    
   (*p).value = data;
    
   
   (*p).prev = head;
    
   
   head = p;
}

void addBack(struct node **head, int val)
{
    
    struct NODE *newNode;
    newNode = malloc(sizeof(struct NODE));
    (*newNode).value = val;
    (*newNode).prev = NULL;

   
    if(*head == NULL)
         *head = newNode;
    else
    {
        struct NODE *headNode = *head;
        while((*headNode).prev != NULL)
        {
            headNode = (*headNode).prev;
        }
        (*headNode).prev = newNode;
    }

}
void printList(struct NODE* head)
{
        while (head != NULL) {
            
        printf("%d",(*head).value);
        
        if((*head).prev!= NULL){
            printf(",");
        }
                head = (*head).prev;
        }
}

void deleteNode(struct NODE** head, int new)
{
    
    struct NODE *tmp = *head, *sa;
    if (tmp != NULL && tmp->value == new) {
        
        free(tmp); 
        return;
    }
    while (tmp != NULL && tmp->value != new) {
        sa = tmp;
        tmp = tmp->prev;
    }
    if (tmp == NULL)
        return;
    sa->prev = tmp->prev;
    free(tmp); 
}
int main()
{
    int num;
    scanf("%d", &num);
    int array[num];
    
    
    for(int i = 0; i < num; i++){
        scanf("%d", &array[i]);
    }
    
    for(int j = num-1; j >= 0; j--){
    insert(array[j]);
    }
    
    int x;
    scanf("%d", &x);
    addBack(&head, x);
    deleteNode(&head, 3);
    printList(head);

    return 0;
}

9 是列表的大小,第三行的随机数 3 只是添加到列表中的新整数。在这个问题中,我试图删除 3 的值,其中有 3 个。输出只删除了 1 所以我想知道问题是什么。

deleteNode() 将最多删除头部或第一个具有匹配值的非头部节点。请注意,在第一种情况下,您需要将 *head 更新为前一个节点。您还应该处理 headNULL.

这是删除所有匹配节点的 deleteNodes() 的实现。为了避免头节点被移除的特殊情况,引入一个 tmp 节点,这样我们只需要处理非头节点的情况:

void deleteNodes(struct NODE **n, int v) {
    if(!n) return;
    struct NODE tmp = {.prev = *n};
    for(struct NODE *p = &tmp; p->prev; ) {
        if(p->prev->value == v) {
            struct NODE *match = p->prev;
            p->prev = p->prev->prev;
            free(match);
        } else {
            p = p->prev;
        }
    }
    *n = tmp.prev;
}