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

如何在c中删除链表中多个变量的多次出现,c,memory-management,struct,linked-list,singly-linked-list,C,Memory Management,Struct,Linked List,Singly Linked List,我是c编程的初学者,几天来我一直在尝试解决以下问题: 如何删除以下列表中至少出现3次的数字: 三,→3.→1.→2.→4.→3.→5.→3.→5.→四, 结果是: 一,→2.→4.→5.→5.→四, 现在我知道如何删除链表中多次出现的“一”键,例如删除链表中所有出现的“1”,但似乎不知道如何删除多个变量的多次出现。这简直要了我的命。如果有人能帮忙,我将不胜感激。提前谢谢。似乎没有人急急忙忙帮你。:) 如果通过引用将指针头传递给函数,则编写函数更简单 下面是一个演示程序,演示如何实现该功能 #in

我是c编程的初学者,几天来我一直在尝试解决以下问题:

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

三,→3.→1.→2.→4.→3.→5.→3.→5.→四,

结果是:

一,→2.→4.→5.→5.→四,


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

似乎没有人急急忙忙帮你。:)

如果通过引用将指针头传递给函数,则编写函数更简单

下面是一个演示程序,演示如何实现该功能

#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;
}
功能
remove\u repeative
可分为两个功能,如下所示

#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;
}
#包括
#包括
结构体类型
{
int数据;
结构节点*下一步;
};
int insert(结构节点**头部,int数据)
{
结构节点*节点=malloc(sizeof(结构节点));
int success=node!=NULL;
如果(成功)
{
节点->数据=数据;
节点->下一步=*头部;
*头部=节点;
}
回归成功;
}
作废(结构节点*头部)
{
for(;head!=NULL;head=head->next)
{
printf(“%d->”,头部->数据);
}
看跌期权(“空”);
}
void remove_all(结构节点**头部,整数数据)
{
while(*head!=NULL)
{
如果((*head)->data==data)
{
结构节点*tmp=*头;
*头部=(*头部)->下一个;
免费(tmp);
}
其他的
{
头部=&(*头部)->下一步;
}
}
}
void remove\u重复(结构节点**头)
{
常数大小限制=3;
while(*head!=NULL)
{
大小\u t计数=1;
int data=(*head)->数据;
对于(结构节点*节点=(*head)->next;
计数next)
{
如果(节点->数据==数据)+计数;
}
如果(计数==限制)
{
移除所有(头部、数据);
}
其他的
{
头部=&(*头部)->下一步;
}
}
}
内部主(空)
{
结构节点*head=NULL;
inta[]={4,5,3,5,3,4,2,1,3,3};
常数大小N=sizeof(a)/sizeof(*a);
对于(大小i=0;i

程序输出与上图相同。

在列表上进行多次传递。例如,一个用来计算所有出现的次数,一个用来删除节点。所以我想这是处理链表的一个练习——扫描和删除项目等等。简单的方法是,对每个键值进行一次扫描(对正好出现两次的键值进行两次扫描)。但那是O(n^2)——啊。要解决这个问题,您需要一些数据结构来收集一次扫描的所有密钥,并识别要删除的密钥。然后在第二次扫描中执行所有删除操作。当然,如果你的列表保证是“短的”:保持简单。代码中的逻辑删除了可被“3”整除的数字,但问题是“删除元素,即出现次数>=3”。是的,这是我的问题,在删除出现>=3次的不同变量的过程中,我总是会丢失头部的轨迹。最后,函数必须将修改后的列表的标题返回给调用方。
#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;
}