Hash表——The Hash table
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#define NAMESIZE 24
#define HASHSIZE 256
typedef LIST HASH;
typedef struct stuinfo{
int id;
char name[NAMESIZE];
int math;
}DATA;
static void print_s(const void *data)
{
const DATA *stup = data;
printf("%d %s %d\n",
stup->id,
stup->name,
stup->math);
}
static int IdCmp(const void *key, const void *data)
{
const int *id = key;
const DATA *stup = data;
return (*id - stup->id);
}
static int NameCmp(const void *key, const void *data)
{
const char *name = key;
const DATA *stup = data;
return strcmp(name, stup->name);
}
int hash_init(HASH *hash, int size)
{
int i, j;
for(i = 0; i < HASHSIZE; i++)
{
hash[i] = ListCreate(size);
if(NULL == hash[i])
{
for(j = 0; j < i; j++)
ListDispose(hash[j]);
return -1;
}
}
return 0;
}
int getnum(int nu)
{
return (nu % HASHSIZE);
}
int hash_insert(HASH *hash, const DATA *data)
{
int i = getnum(data->id);
return ListInsert(hash[i], data, HEADINSERT);
}
void hash_display(HASH *hash)
{
int i;
int count = 0;
for(i = 0; i < HASHSIZE; i++)
{
count = 0;
PtrNode p = hash[i]->head.next;
for(; p != &hash[i]->head; p = p->next, count++);
printf("%d ", count);
}
printf("\n");
}
void hash_dispose(HASH *hash)
{
int i;
for(i = 0; i < HASHSIZE; i++)
{
ListDispose(hash[i]);
hash[i] = NULL;
}
}
void *hash_find(HASH *hash, int id)
{
int i = getnum(id);
return ListFind(hash[i], &id, IdCmp);
}
int main()
{
int i;
int id = 5;
char name[NAMESIZE] = "stu3";
DATA stu, *stup;
HASH hash[HASHSIZE] = {0};
hash_init(hash, sizeof(DATA));
srand(time(NULL));
for(i = 0; i < 9999; i++)
{
id = stu.id = rand();
snprintf(stu.name,NAMESIZE,
"stu%d", i + 1);
stu.math = rand() % 100;
hash_insert(hash, &stu);
}
stup = hash_find(hash, id);
if(stup == NULL)
printf("not find\n");
else
print_s(stup);
hash_display(hash);
hash_dispose(hash);
return 0;
}
-----------------------------------------------------------
#ifndef _LIST_H__
#define _LIST_H__
#define HEADINSERT 1
#define TAILINSERT 2
struct listnode;
struct headnode;
typedef struct headnode *LIST;
typedef struct listnode *PtrNode;
typedef void print(const void *);
typedef int cmp(const void *, const void *);
LIST ListCreate(int);
int ListInsert(LIST, const void *, int);
void *ListFind(LIST, const void *, cmp *);
int ListDelete(LIST, const void *, cmp *);
int ListFetch(LIST, const void *, cmp *, void *);
void ListDisplay(LIST, print *);
void ListDispose(LIST);
struct listnode{
void *data;
struct listnode *prev;
struct listnode *next;
};
struct headnode{
int size;
struct listnode head;
};
#endif
---------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
LIST ListCreate(int size)
{
LIST handle = malloc(sizeof(*handle));
if(NULL == handle)
return NULL;
handle->size = size;
handle->head.data = NULL;
handle->head.prev = handle->head.next = &handle->head;
return handle;
}
int ListInsert(LIST l, const void *data, int mode)
{
PtrNode cur = malloc(sizeof(*cur));
if(NULL == cur)
return -1;
cur->data = malloc(l->size);
if(NULL == cur->data)
{
free(cur);
return -2;
}
memcpy(cur->data, data, l->size);
if(mode == HEADINSERT)
{
cur->next = l->head.next;
cur->prev = &l->head;
}
else if(mode == TAILINSERT)
{
cur->next = &l->head;
cur->prev = l->head.prev;
}
else
{
free(cur->data);
free(cur);
return -3;
}
cur->prev->next = cur;
cur->next->prev = cur;
return 0;
}
static PtrNode find(LIST l, const void *key, cmp *funp)
{
PtrNode p = l->head.next;
for(;p != &l->head && funp(key, p->data); p = p->next);
return p;
}
void *ListFind(LIST l, const void *key, cmp *funp)
{
return find(l, key, funp)->data;
}
int ListDelete(LIST l, const void *key, cmp *funp)
{
PtrNode p = find(l, key, funp);
if(p == &l->head)
return -1;
p->prev->next = p->next;
p->next->prev = p->prev;
//p->prev = p->next = NULL;
free(p->data);
free(p);
//p = NULL;
return 0;
}
int ListFetch(LIST l, const void *key, cmp * funp, void *data)
{
PtrNode p = find(l, key, funp);
if(p == &l->head)
return -1;
memcpy(data, p->data, l->size);
p->prev->next = p->next;
p->next->prev = p->prev;
//p->prev = p->next = NULL;
free(p->data);
free(p);
//p = NULL;
return 0;
}
void ListDisplay(LIST l, print *funp)
{
PtrNode p = l->head.next;
while(p != &l->head)
{
funp(p->data);
p = p->next;
}
}
void ListDispose(LIST l)
{
PtrNode p = l->head.next;
PtrNode q;
while(p != &l->head)
{
q = p;
p = p->next;
free(q->data);
free(q);
}
free(l);
}