我有一个联系结构插入到哈希表中的链表中。我不知道我是否正确定义了所有结构。 我基本上想在给定命令'a'时通过输入添加联系人(命令将像这样:一个姓名电话)。 如果联系人已经存在,我将无法添加。
我尝试用链接列表创建哈希表的必要结构,但我只是不知道如何使用它。因此,此功能将有助于我理解该概念。
这是我尝试过的结构
#define NOME_SIZE 1023
#define MAIL_SIZE 511
#define TELEFONE_SIZE 63
#define HASH_SIZE 1000
typedef struct contacts{
char name[NOME_SIZE];
char mail[MAIL_SIZE];
char phone[TELEFONE_SIZE];
struct contacts *next;
}HashList;
typedef struct hash_bucket{
HashList *head, *tail;
int n_elements;
}HashBucket;
HashBucket hashtable[HASH_SIZE];
如果可以成功添加联系人,我不希望有任何输出。 如果已经存在,则应返回错误消息,说明联系人已经存在
答案 0 :(得分:0)
您的代码中的建议和我的评论。我删除了n_elements
,因为对我来说这没用。我允许 tail 使用,但不确定是否有用,因为您的列表中只有 next 和 previous 。我让名称,电话和邮件使用数组,但我认为最好使用char *
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOME_SIZE 1023
#define MAIL_SIZE 511
#define TELEFONE_SIZE 63
#define HASH_SIZE 1000
typedef struct contacts{
char name[NOME_SIZE];
char mail[MAIL_SIZE];
char phone[TELEFONE_SIZE];
struct contacts *next;
}HashList;
typedef struct hash_bucket{
HashList *head, *tail;
/* int n_elements; * I removed that field, it is useless */
}HashBucket;
HashBucket hashtable[HASH_SIZE];
// from https://stackoverflow.com/a/7666577/2458991
size_t hash(char * str)
{
size_t hash = 5381;
unsigned char c;
while ((c = (unsigned char) *str++) != 0)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
HashList * createElt(char * n, char * m, char * p)
{
HashList * e = malloc(sizeof(HashList));
strncpy(e->name, n, NOME_SIZE - 1);
e->name[NOME_SIZE - 1] = 0;
strncpy(e->mail, m, MAIL_SIZE - 1);
e->name[MAIL_SIZE - 1] = 0;
strncpy(e->phone, p, TELEFONE_SIZE - 1);
e->name[TELEFONE_SIZE - 1] = 0;
e->next = NULL;
return e;
}
// add or replace an element, the key is the name
// return 0 if the entry is added, else a non null value if the entry is (probably) modified
int insertElt(char * n, char * m, char * p)
{
// suppose list sort on the name
HashBucket * hb = &hashtable[hash(n) % HASH_SIZE];
HashList ** hl = &hb->head;
for (;;) {
if (*hl == NULL) {
/* last (and may be first) element */
*hl = createElt(n, m, p);
hb->tail = *hl;
return 0;
}
int cmp = strcmp((*hl)->name, n);
if (cmp == 0) {
/* replace */
strncpy((*hl)->mail, m, MAIL_SIZE - 1);
(*hl)->name[MAIL_SIZE - 1] = 0;
strncpy((*hl)->phone, p, TELEFONE_SIZE - 1);
(*hl)->name[TELEFONE_SIZE - 1] = 0;
return 1;
}
if (cmp > 0) {
/* insert before */
HashList * e = createElt(n, m, p);
e->next = *hl;
*hl = e;
return 0;
}
hl = &(*hl)->next;
}
}
void pr()
{
for (size_t i = 0; i != HASH_SIZE; ++i)
for (HashList * hl = hashtable[i].head; hl != NULL; hl = hl->next)
printf("%s %s %s\n", hl->name, hl->mail, hl->phone);
}
int main()
{
printf("%d\n", insertElt("n1", "m1", "p1"));
printf("%d\n", insertElt("n2", "m2", "p2"));
pr();
printf("%d\n", insertElt("n1", "mm1", "pp1"));
pr();
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall hm.c
pi@raspberrypi:/tmp $ ./a.out
0
0
n1 m1 p1
n2 m2 p2
1
n1 mm1 pp1
n2 m2 p2