如何删除c中链表中多次出现的多个变量

How to delete multiple occurrences of multiple variables in a linked list in c

我是 c 编程的初学者,我已经尝试了几天来解决以下问题:

如何删除在以下列表中出现至少 3 次的数字:

3→3→1→2→4→3→5→3→5→4

这使得结果:

1→2→4→5→5→4.

现在我知道如何删除链表中多次出现的"one"键,例如删除链表中所有出现的“1”,但似乎无法理解如何删除多个多个变量的出现。这简直要了我的命。如果有人能提供帮助,我将不胜感激。提前致谢。

看来没人急着帮你:)

如果将指针head通过引用传递给函数,写函数会更简单。

这是一个演示程序,展示了如何实现该功能。

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

struct Node
{
    int data;
    struct Node *next;
};

int insert( struct Node **head, int data )
{
    struct Node *node = malloc( sizeof( struct Node ) );
    int success = node != NULL;

    if ( success )
    {
        node->data = data;
        node->next = *head;
        *head = node;
    }

    return success;
}

void out( struct Node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }
    puts( "null" );
}

void remove_repetitive( struct Node **head )
{
    const size_t LIMIT = 3;

    while ( *head != NULL )
    {
        size_t count = 1;

        int data = ( *head )->data;

        for ( struct Node *node = ( *head )->next; 
              count < LIMIT && node != NULL; node = node->next )
        {
            if ( node->data == data ) ++count;
        }

        if ( count == LIMIT )
        {
            for ( struct Node **node = head; *node != NULL; )
            {
                if ( ( *node )->data == data )
                {
                    struct Node *tmp = *node;
                    *node = ( *node )->next;
                    free( tmp );
                }
                else
                {
                    node = &( *node )->next;
                }
            }
        }
        else
        {
            head = &( *head )->next;
        }
    }
}

int main(void) 
{
    struct Node *head = NULL;
    int a[] = { 4, 5, 3, 5, 3, 4, 2, 1, 3, 3 };

    const size_t N = sizeof( a ) / sizeof( *a );

    for ( size_t i = 0; i < N; i++ )
    {
        insert( &head, a[i] );
    }

    out( head );

    remove_repetitive( &head );

    out( head );

    return 0;
}

程序输出为

3 -> 3 -> 1 -> 2 -> 4 -> 3 -> 5 -> 3 -> 5 -> 4 -> null
1 -> 2 -> 4 -> 5 -> 5 -> 4 -> null

函数 remove_repetitive 可以拆分为两个函数,如下所示。

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

struct Node
{
    int data;
    struct Node *next;
};

int insert( struct Node **head, int data )
{
    struct Node *node = malloc( sizeof( struct Node ) );
    int success = node != NULL;

    if ( success )
    {
        node->data = data;
        node->next = *head;
        *head = node;
    }

    return success;
}

void out( struct Node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }
    puts( "null" );
}

void remove_all( struct Node **head, int data )
{
    while ( *head != NULL )
    {
        if ( ( *head )->data == data )
        {
            struct Node *tmp = *head;
            *head = ( *head )->next;
            free( tmp );
        }
        else
        {
            head = &( *head )->next;
        }
    }
}

void remove_repetitive( struct Node **head )
{
    const size_t LIMIT = 3;

    while ( *head != NULL )
    {
        size_t count = 1;

        int data = ( *head )->data;

        for ( struct Node *node = ( *head )->next; 
              count < LIMIT && node != NULL; node = node->next )
        {
            if ( node->data == data ) ++count;
        }

        if ( count == LIMIT )
        {
            remove_all( head, data );   
        }
        else
        {
            head = &( *head )->next;
        }
    }
}

int main(void) 
{
    struct Node *head = NULL;
    int a[] = { 4, 5, 3, 5, 3, 4, 2, 1, 3, 3 };

    const size_t N = sizeof( a ) / sizeof( *a );

    for ( size_t i = 0; i < N; i++ )
    {
        insert( &head, a[i] );
    }

    out( head );

    remove_repetitive( &head );

    out( head );

    return 0;
}

程序输出同上图