我有这个结构:
typedef struct data student, *pstudent;
struct data{
char name[50];
int value;
pstudent next;
};
我需要一个能够找到未排序链表中最常见学生的函数。 例如: “约翰 - 价值3” “大卫 - 价值2” “安德鲁 - 价值4” “约翰 - 价值9” 在这种情况下,函数将返回“John”,因为他出现了两次。
到目前为止代码:
void count(pstudent p)
{
pstudent ptr1, ptr2;
ptr1 = p;
while(ptr1 != NULL && ptr1->next!=NULL)
{
ptr2 = ptr1;
while(ptr2->next != NULL)
{
if(strcmp(ptr1->name,ptr2->next->name)==0)
{
printf("Found %s, %s", ptr1->name,ptr2->name);
}
}
ptr1 = ptr1->next;
}
}
我该如何使这项工作? 谢谢你的帮助。
答案 0 :(得分:2)
如果要最小化内存使用,请遍历列表一次。对于您遇到的每个名称,计算它在列表中当前位置之后也出现的次数。记录具有最高计数(及其计数)的名称。第一次遇到名称将为您提供该名称的最高计数。这是一个O(N 2 )算法,但只需要存储指向具有最大计数和最大计数的名称的指针。成本是它在大型列表上很慢。
主要的替代方案是使用一些算法来记录遇到的名称,并在遇到列表中的每个名称时增加与该名称关联的计数。这可能是unxnut建议的哈希函数,也可能使用不同名称的直接副本或指针。它需要某种类型的数组,因此对于大型列表,它可能需要大量存储(但只要您对数组管理小心,就是O(N)算法。)
因此,您将获得经典的时空权衡。很多将取决于您要处理的数据集的大小以及数据集中的重复量。对于小批量生产最有效的方法可能无法在大批量生产中发挥最佳作用。
答案 1 :(得分:1)
一种方法是使用密钥转换或散列函数。在名称上使用哈希值,如果哈希值匹配,则将该名称的计数增加1。返回计数最高的那个。