如何在c中删除链表中多个变量的多次出现
我是c编程的初学者,几天来我一直在尝试解决以下问题: 如何删除以下列表中至少出现3次的数字: 三,→3.→1.→2.→4.→3.→5.→3.→5.→四, 结果是: 一,→2.→4.→5.→5.→四,如何在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
现在我知道如何删除链表中多次出现的“一”键,例如删除链表中所有出现的“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;
}