在这里,我对作业和代码中的问题有非常详细的说明。作业分为两部分,第一部分的代码有效,但第二部分的代码修改后不再起作用。
家庭作业:使用字典来保存人的名字和最快的运行时间(使用开放式哈希,即字典用哈希表表示,哈希表是具有B个元素的数组,其中每个元素数组是单元格类型元素的链接列表。哈希表使用哈希函数h(name),其中对于i = 1,...,B-1,如果h(name)= i,则有关具有“名称”保存在字典第i个元素的链接列表中。人们按其姓名排序。)
这是它的样子。
#define B 20
typedef struct celltag{
char name[11];
double time;
struct celltag *next;
} celltype;
typedef celltype **Dictionary;
int h(char name[]){
int i, sum=0;
for(i=0;name[i]!='\0';i++) {
sum+=name[i];
}
return sum % B;
}
void DiMakeNull (Dictionary *Ap){
int i;
for(i=0;i<B;i++) (*Ap)[i]=NULL;
}
void DiInsert(char name[], double time, Dictionary *Ap){
int bucket;
celltype *oldheader;
if(DiMember(name, *Ap)==0){
bucket=h(name);
oldheader=(*Ap)[bucket];
(*Ap)[bucket]=(celltype*)malloc(sizeof(celltype));
strcpy((*Ap)[bucket]->name, name);
(*Ap)[bucket]->time= time;
(*Ap)[bucket]->next=oldheader;
}
}
(函数DiMember(char name [],字典A)如果有人在字典中,则返回1,否则返回0。)
这部分应该正常工作。
现在,作业的下一部分:使用另一个指针数组按人员的跑步时间对其进行排序,该数组的第一个元素指向最快的人的数据,第二个元素指向第二个最快的人人等。
我的想法是制作另一个字典,我们称之为字典数组。 现在,在将一个新人的数据插入原始词典Ap的同时,我想调用另一个函数void Sort(celltype * Data,Dictionary * Array),该函数采用存储新人数据的单元格类型以及我们将在其中插入的Array它按时间排序。
因为我会在DiInsert中使用它,所以将其修改为
void DiInsert(char name[], double time, Dictionary *Ap, Dictionary *Array){
int bucket;
celltype *oldheader;
if(DiMember(name, *Ap, 0)==0){
bucket=h(name);
oldheader=(*Ap)[bucket];
(*Ap)[bucket]=(celltype*)malloc(sizeof(celltype));
strcpy((*Ap)[bucket]->name, name);
(*Ap)[bucket]->time= time;
(*Ap)[bucket]->next=oldheader;
celltype *send;
send=(*Ap)[bucket];
send->next=NULL;
Sort(send, Array);
}
}
(一切都一样,只是我在函数中添加了另一个参数,并在末尾添加了该位(单元格类型* send; ... Sort(send(send,Array);)。)
函数的外观如下:
void Sort(celltype* Data, Dictionary *Array){
if ((*Array)[0]==NULL){
(*Array)[0]=Data;
(*Array)[0]->next=NULL;
}
else{
int i;
for(i=0;(*Array)[i]!=NULL;i++){
if(Data->time < (*Array)[i]->time){
celltype *new;
new=(*Array)[i];
(*Array)[i]=new;
(*Array)[i]->next=NULL;
int j=i+1;
while((*Array)[j]!=NULL){
celltype *old;
old=(*Array)[j];
(*Array)[j]=new;
(*Array)[j]->next=NULL;
new=old;
j++;
}
(*Array)[j]=new;
(*Array)[j]->next=NULL;
break;
}
}
}
}
这些是我的问题:
调用函数Sort / function参数时出现问题。我在理解指针时仍然遇到一些问题,因此我不确定如何解决它。
在修改DiInsert之前,代码的第一位有效。现在,在修改并添加了void Sort()之后,由于某种原因,有时它会将原始Dictionary Ap中的数据加倍,并将其保存在正确的第i个括号中,并且也保存在其他一些括号中。
< / li>它还会使Dictionary Array中的数据加倍。例如,如果我输入“ Mark”作为名称,并输入10.1作为时间,则h(Mark)= 15,因此它将Mark的数据保存在Dictionary Ap的第15个括号中。然后,它将Mark的数据保存在Dictionary Array的第0个括号中(这是应该的,因为Mark的数据是第一个输入的数据,并且他现在是最快的数据),但它也将其保存在第16个括号中。为什么?
答案 0 :(得分:0)
您通常不能使用字典来存储排序结果,因为这些是为快速随机访问而不是排序访问而设计的数据结构。您应该使用一个数组并对数组进行排序。
但是,由于您已经在字典中拥有所有元素,因此生成数组然后进行排序将很简单。毕竟,因为这是一项家庭作业,所以我将概述这个想法,然后让您填写其余内容:
celltype
个元素的数量并将其存储到total_elements
celltype *
的长度为total_elements
的类型sort_array
的新数组celltype
元素的地址添加到sort_array
sort_compare_func()
来实现您要实现的排序顺序sort_array
和total_elements
在sort_compare_func()
上运行排序算法我不确定您的作业是否需要您实现自己的排序算法。我的代码片段将使用标准的POSIX函数qsort()
:
// compare function for sort algorithm
static int sort_compare_func(const void *a, const void *b) {
// called with pointers to (celltype *) elements in array
double timeA = (*(celltype **) a)->time;
double timeB = (*(celltype **) b)->time;
// < 0 : a faster than b
if (timeA < timeB) return(-1);
// > 0 : b faster than a
if (timeB < timeA) return( 1);
// == 0 : a same time as b
return(0);
}
....
unsigned int total_elements = count_elements_in_dictionary(Ap);
celltype **sort_array = malloc(total_elements * sizeof(celltype *));
// fill the array
fill_sort_array_from_dictionary(Ap, sort_array);
// sort_array[0] points to the first celltype element found in Dictionary
// sort_array[total_elements - 1] points to the last celltype element found in Dictionary
// sort array using POSIX quick sort implementation
qsort(sort_array, total_elements, sizeof(celltype *), sort_compare_func);
// sort_array[0] points to the celltype element with the smallest time
// sort_array[total_elements - 1] points to the celltype element with the largest time
celltype *winner = sort_array[0];
printf("and the winner is: %s with %f\n", winner->name, winner->time);
简单的测试代码:100个元素,随机时间为0到100:
#include <stdlib.h>
#include <time.h>
....
unsigned int total_elements = 100;
....
//fill_sort_array_from_dictionary(Ap, sort_array);
srand(time(NULL));
celltype *data = malloc(total_elements * sizeof(celltype));
for (int i = 0; i < total_elements; i++) {
sprintf(data[i].name, "%04d", i);
data[i].time = (rand() * 100.0) / RAND_MAX;
sort_array[i] = &data[i];
}
...
一些测试运行:
$ gcc -Wall -o dummy dummy.c
$ ./dummy
and the winner is: 0085 with 0.165149
and the looser is: 0066 with 99.612887
$ ./dummy
and the winner is: 0044 with 0.484525
and the looser is: 0006 with 98.964099
$ ./dummy
and the winner is: 0066 with 0.293111
and the looser is: 0016 with 99.822637
希望这会有所帮助。