c语言中contune的作用,【c语言】通用哈希表

#include

#include

#include

#include

//启用断言

#define DEBUG

#define HASH_MAX 101

#define ERR_EXIT(m) (perror(m), exit(EXIT_FAILURE))

typedef struct _hashnode //哈希结点

{

void *key;

void *value;

struct _hashnode *prev;

struct _hashnode *next;

} HASH_NODE;

typedef struct _hashlink //哈希链表

{

HASH_NODE *head;

HASH_NODE *rear;

unsigned int len;

} HASH_LINK;

typedef struct _hashtable //通用哈希表

{

unsigned int len;

unsigned int hash_max;

HASH_LINK *hash_link;

unsigned int (*T_hash_fun)(void *key);

} HASH_TABLE;

void* memdup(const void *src, unsigned int len);

void hash_init(HASH_TABLE **hash_table, unsigned int

(*hash_fun)(void *key));

void* hash_first_insert(HASH_TABLE *hash_table, void *key, unsigned

int key_len, void *val, unsigned int val_len);

void* hash_last_insert(HASH_TABLE *hash_table, void *key, unsigned

int key_len, void *val, unsigned int val_len);

int hash_first_delete(HASH_TABLE *hash_table, void* key, unsigned

int key_len, void *val, unsigned int val_len);

int hash_last_delete(HASH_TABLE *hash_table, void* key, unsigned

int key_len, void *val, unsigned int val_len);

int hash_first_set(HASH_TABLE *hash_table, void* key, unsigned int

key_len, void *val, unsigned int val_len);

int hash_last_set(HASH_TABLE *hash_table, void* key, unsigned int

key_len, void *val, unsigned int val_len);

HASH_NODE * hash_first_search(HASH_TABLE *hash_table, void *key,

unsigned int key_len, void *val, unsigned int val_len);

HASH_NODE * hash_last_search(HASH_TABLE *hash_table, void *key,

unsigned int key_len, void *val, unsigned int val_len);

void* hash_get_first_value(HASH_TABLE *hash_table, void* key,

unsigned int key_len);

void* hash_get_last_value(HASH_TABLE *hash_table, void* key,

unsigned int key_len);

void hash_clear(HASH_TABLE *hash_table);

void hash_destroy(HASH_TABLE **hash_table);

unsigned int hash_fun1(void *key);

unsigned int hash_fun2(void *key);

unsigned int hash_fun3(void *key);

unsigned int hash_fun4(void *key);

unsigned int hash_fun5(void *key);

unsigned int hash_fun6(void *key);

unsigned int hash_fun7(void *key);

unsigned int hash_fun8(void *key);

unsigned int hash_fun9(void *key);

unsigned int hash_fun10(void *key);

unsigned int hash_fun11(void *key);

void* memdup(const void *src, unsigned int len)

{

void *p;

if(!src)

return NULL;

p = malloc(len);

if(!p)

{

ERR_EXIT("memdup: malloc");

}

memcpy(p, src, len);

return p;

}

void hash_init(HASH_TABLE **hash_table, unsigned int

(*hash_fun)(void *key))

{

HASH_TABLE *hash;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != hash_fun);

#endif

*hash_table = (HASH_TABLE *)malloc(sizeof(HASH_TABLE));

hash = *hash_table;

if(!hash)

{

ERR_EXIT("hash_init: malloc");

}

hash->len = 0;

hash->hash_max = HASH_MAX;

hash->hash_link = (HASH_LINK *)calloc(HASH_MAX,

sizeof(HASH_LINK));

if(!(hash->hash_link))

{

ERR_EXIT("hash_init: calloc");

}

memset(hash->hash_link, 0, HASH_MAX *

sizeof(HASH_LINK));

hash->T_hash_fun = hash_fun;

}

void* hash_first_insert(HASH_TABLE *hash_table, void *key, unsigned

int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *phead, *tmp;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

tmp = (HASH_NODE *)malloc(sizeof(HASH_NODE));

if(!tmp)

{

ERR_EXIT("hash_first_insert: malloc");

}

tmp->key = memdup(key, key_len);

tmp->value = memdup(val, val_len);

tmp->prev = tmp->next = NULL;

index = hash_table->T_hash_fun(key);

phead = hash_table->hash_link[index].head;

if(!phead)

{

hash_table->hash_link->head =

hash_table->hash_link->rear =

tmp;

} else

{

tmp->next = phead;

phead->prev = tmp;

phead = tmp;

}

hash_table->len += 1;

hash_table->hash_link[index].len += 1;

return tmp->key;

}

void* hash_last_insert(HASH_TABLE *hash_table, void *key, unsigned

int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *prear, *tmp;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

tmp = (HASH_NODE *)malloc(sizeof(HASH_NODE));

if(!tmp)

{

ERR_EXIT("hash_first_insert: malloc");

}

tmp->key = memdup(key, key_len);

tmp->value = memdup(val, val_len);

tmp->prev = tmp->next = NULL;

index = hash_table->T_hash_fun(key);

prear = hash_table->hash_link[index].rear;

if(!prear)

{

hash_table->hash_link->head =

hash_table->hash_link->rear =

tmp;

} else

{

tmp->prev = prear;

prear->next = tmp;

prear = tmp;

}

hash_table->len += 1;

hash_table->hash_link[index].len += 1;

return tmp->key;

}

int hash_first_delete(HASH_TABLE *hash_table, void* key, unsigned

int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *p, *phead, *prear;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_first_search(hash_table, key, key_len, val,

val_len);

if(!p)

{

return 0;

}

index = hash_table->T_hash_fun(key);

phead = hash_table->hash_link[index].head;

prear = hash_table->hash_link[index].rear;

if(phead == p)

{

phead = phead->next;

hash_table->hash_link[index].head = phead;

}

else if(prear == p)

{

prear = prear->prev;

hash_table->hash_link[index].rear = prear;

}

else

{

p->prev->next =

p->next;

p->next->prev =

p->prev;

}

free(p->key);

free(p->value);

free(p);

if(!phead || !prear)

hash_table->hash_link[index].head =

hash_table->hash_link[index].rear = NULL;

hash_table->len -= 1;

hash_table->hash_link[index].len -= 1;

return 1;

}

int hash_last_delete(HASH_TABLE *hash_table, void* key, unsigned

int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *p, *phead, *prear;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_last_search(hash_table, key, key_len, val, val_len);

if(!p)

{

return 0;

}

index = hash_table->T_hash_fun(key);

phead = hash_table->hash_link[index].head;

prear = hash_table->hash_link[index].rear;

if(phead == p)

{

phead = phead->next;

hash_table->hash_link[index].head = phead;

}

else if(prear == p)

{

prear = prear->prev;

hash_table->hash_link[index].rear = prear;

}

else

{

p->prev->next =

p->next;

p->next->prev =

p->prev;

}

free(p->key);

free(p->value);

free(p);

if(!phead || !prear)

hash_table->hash_link[index].head =

hash_table->hash_link[index].rear = NULL;

hash_table->len -= 1;

hash_table->hash_link[index].len -= 1;

return 1;

}

int hash_first_set(HASH_TABLE *hash_table, void* key, unsigned int

key_len, void *val, unsigned int val_len)

{

HASH_NODE *p;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_first_search(hash_table, key, key_len, NULL, 0);

if(!p)

{

return 0;

}

p->value = memdup(val, val_len);

return 1;

}

int hash_last_set(HASH_TABLE *hash_table, void* key, unsigned int

key_len, void *val, unsigned int val_len)

{

HASH_NODE *p;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_last_search(hash_table, key, key_len, NULL, 0);

if(!p)

{

return 0;

}

p->value = memdup(val, val_len);

return 1;

}

HASH_NODE * hash_first_search(HASH_TABLE *hash_table, void *key,

unsigned int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *p = NULL;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

index = hash_table->T_hash_fun(key);

p = hash_table->hash_link[index].head;

if(val)

{

for(; p; p = p->next)

{

if(!memcmp(p->key, key, key_len)

&& !memcmp(p->value,

val, val_len))

return p;

}

} else

{

for(; p; p = p->next)

{

if(!memcmp(p->key, key, key_len))

return p;

}

}

return NULL;

}

HASH_NODE * hash_last_search(HASH_TABLE *hash_table, void *key,

unsigned int key_len, void *val, unsigned int val_len)

{

unsigned int index;

HASH_NODE *p = NULL;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

index = hash_table->T_hash_fun(key);

p = hash_table->hash_link[index].rear;

if(val)

{

for(; p; p = p->prev)

{

if(!memcmp(p->key, key, key_len)

&& !memcmp(p->value,

val, val_len))

return p;

}

} else

{

for(; p; p = p->prev)

{

if(!memcmp(p->key, key, key_len))

return p;

}

}

return NULL;

}

void* hash_get_first_value(HASH_TABLE *hash_table, void* key,

unsigned int key_len)

{

HASH_NODE *p;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_first_search(hash_table, key, key_len, NULL, 0);

if(!p)

{

return NULL;

}

return p->value;

}

void* hash_get_last_value(HASH_TABLE *hash_table, void* key,

unsigned int key_len)

{

HASH_NODE *p;

#ifdef DEBUG

assert(NULL != hash_table);

assert(NULL != key);

#endif

p = hash_last_search(hash_table, key, key_len, NULL, 0);

if(!p)

{

return NULL;

}

return p->value;

}

void hash_clear(HASH_TABLE *hash_table)

{

int i;

HASH_NODE *p;

#ifdef DEBUG

assert(NULL != hash_table);

#endif

for(i=0; i

{

if(hash_table->hash_link[i].head)

{

while(p = hash_table->hash_link[i].head)

{

hash_table->hash_link[i].head =

hash_table->hash_link[i].head->next;

free(p->key);

free(p->value);

free(p);

} //while

} //if

} //for

memset(hash_table->hash_link, 0, HASH_MAX *

sizeof(HASH_LINK));

hash_table->len = 0;

}

void hash_destroy(HASH_TABLE **hash_table)

{

int i;

HASH_NODE *p;

HASH_TABLE *hash;

#ifdef DEBUG

assert(NULL != hash_table);

#endif

hash = *hash_table;

for(i=0; i

{

if(hash->hash_link[i].head)

{

while(p = hash->hash_link[i].head)

{

hash->hash_link[i].head =

hash->hash_link[i].head->next;

free(p->key);

free(p->value);

free(p);

} //while

} //if

} //for

free(hash->hash_link);

free(hash);

*hash_table = NULL;

}

unsigned int hash_fun1(void* str)

{

char *tmp;

unsigned int b = 378551;

unsigned int a = 63689;

unsigned int hash = 0;

unsigned int i = 0;

tmp = (char *)str;

while(*tmp)

{

hash = hash * a + (*tmp++);

a = a * b;

}

return hash % HASH_MAX;

}

unsigned int hash_fun2(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 1315423911;

unsigned int i = 0;

while(*tmp)

{

hash ^= ((hash << 5) + (*tmp++) +

(hash >> 2));

}

return hash % HASH_MAX;

}

unsigned int hash_fun3(void *key)

{

char *tmp = (char *)key;

const unsigned int BitsInUnsignedInt = (unsigned

int)(sizeof(unsigned int) * 8);

const unsigned int ThreeQuarters = (unsigned

int)((BitsInUnsignedInt * 3) / 4);

const unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt /

8);

const unsigned int HighBits = (unsigned int)(0xFFFFFFFF)

<< (BitsInUnsignedInt -

OneEighth);

unsigned int hash = 0;

unsigned int test = 0;

unsigned int i = 0;

while(*tmp)

{

hash = (hash << OneEighth) +

(*tmp++);

if((test = hash & HighBits) != 0)

{

hash = (( hash ^ (test >>

ThreeQuarters)) & (~HighBits));

}

}

return hash % HASH_MAX;

}

unsigned int hash_fun4(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 0;

unsigned int x = 0;

unsigned int i = 0;

while(*tmp)

{

hash = (hash << 4) + (*tmp++);

if((x = hash & 0xF0000000L) != 0)

{

hash ^= (x >> 24);

}

hash &= ~x;

}

return hash % HASH_MAX;

}

unsigned int hash_fun5(void *key)

{

char *tmp;

unsigned int hash = 0;

tmp = (char*)key;

hash = 0;

while(*tmp)

{

hash = (*tmp++) + hash*131;

}

return hash % HASH_MAX;

}

unsigned int hash_fun6(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 0;

unsigned int i = 0;

while(*tmp)

{

hash = (*tmp++) + (hash << 6) + (hash

<< 16) - hash;

}

return hash % HASH_MAX;

}

unsigned int hash_fun7(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 5381;

unsigned int i = 0;

while(*tmp)

{

hash = ((hash << 5) + hash) +

(*tmp++);

}

return hash % HASH_MAX;

}

unsigned int hash_fun8(void *key)

{

char *tmp = (char *)key;

unsigned int hash = strlen(tmp);

unsigned int i = 0;

while(*tmp)

{

hash = ((hash << 5) ^ (hash

>> 27)) ^ (*tmp++);

}

return hash % HASH_MAX;

}

unsigned int hash_fun9(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 0;

unsigned int i = 0;

while(*tmp)

{

hash = hash << 7 ^ (*tmp++);

}

return hash % HASH_MAX;

}

unsigned int hash_fun10(void *key)

{

char *tmp = (char *)key;

const unsigned int fnv_prime = 0x811C9DC5;

unsigned int hash = 0;

unsigned int i = 0;

while(*tmp)

{

hash *= fnv_prime;

hash ^= (*tmp++);

}

return hash % HASH_MAX;

}

unsigned int hash_fun11(void *key)

{

char *tmp = (char *)key;

unsigned int hash = 0xAAAAAAAA;

unsigned int i = 0;

while(*tmp)

{

hash ^= ((i & 1) == 0) ? ( (hash

<< 7) ^ (*tmp++) * (hash

>> 3)) :

(~((hash << 11) + ((*tmp++) ^ (hash

>> 5))));

}

return hash % HASH_MAX;

}

int main()

{

unsigned int (*HASH_FUN[])(void *) =

{ hash_fun1, hash_fun2, hash_fun3, hash_fun4, hash_fun5,

hash_fun6, hash_fun7, hash_fun8, hash_fun9, hash_fun10,

hash_fun11

};

char *keywords[] =

{

"auto","break","case","char","const","continue","default","do",

"double","else","enum","extern","float","for","goto","if",

"int","long","register","return","short","signed","sizeof","static",

"struct","switch","typedef","union","unsigned","void","volatile","while",

"auto1","break1","case1","char1","const1","continue1","default1","do1",

"double1","else1","enum1","extern1","float1","for1","goto1","if1",

"int1","long1","registe1r","return1","short1","signed1","sizeof1","static1",

"struct1","switch1","typedef1","union1","unsigned1","void1","volatile1","while1",

"auto2","br2eak","ca2se","c2har","con2st","c2ontinue","de2fault","d2o",

"double22","els2e","enum2","ext2ern","flo2at","fo2r","go2to","i2f",

"int2","l2ong","regist2er","ret2urn","shor2t","sign2ed","siz2eof","st2atic",

"struct2","switch2","typedef2","union2","unsigned2","void2","volat2ile","w2hile",

"au3to","br3eak","ca3se","ch3ar","co3nst","co3ntinue","def3ault","3do",

"doub3le","els3e","enu3m","ext3ern","floa3t","fo3r","go3to","3if",

"in3t","lo3ng","re3gister","r3eturn","s3hort","si3gned","s3izeof","sta3tic",

"struc3t","swi3tch","typ3edef","uni3on","unsi3gned","v3oid","vola3tile","wh3ile",

"1", "3", "5", "7", "9", "12", "45", "78",

"2", "4", "6", "8", "0", "21", "54", "87",

"11", "33", "55", "77", "99", "23", "56", "89",

"22", "44", "66", "88", "00", "98", "32", "65",

"111", "333", "555", "777", "999", "34", "67", "90",

"222", "444", "666", "888", "000", "43", "76", "09",

"1a", "3b", "5c", "7dddddd", "9eeeeee", "12f", "45gggggg",

"78h",

"2aa", "4bb", "6cccccc", "8ddddd", "0eeeee", "21ff", "54ggggg",

"87hh",

"11aaa", "33bbb", "55ccccc", "77dddd", "99eeee", "23fff", "56gggg",

"89hhh",

"22aaaa", "44bbbb", "66cccc", "88ddd", "00eee", "98ffff", "32ggg",

"65hhhh",

"111aaaaa", "333bbbbb", "555ccc", "777dd", "999ee", "34fffff",

"67gg", "90hhhhh",

"222aaaaaa", "444bbbbbb", "666cc", "888d", "000e", "43ffffff",

"76g", "09hhhhhh"

};

int i, j, size, sum[11] = {0};

HASH_TABLE *hash_table[11];

for(i=0; i<11; i++)

hash_init(hash_table+i, HASH_FUN[i]);

size = sizeof(keywords) / sizeof(keywords[0]);

for(i=0; i<11; i++)

{

for(j=0; j

{

hash_first_insert(hash_table[i], keywords[j], sizeof(keywords[j]),

NULL, 0);

}

}

for(i=0; i<11; i++)

{

for(j=0; j

{

if(0 == hash_table[i]->hash_link[j].len)

sum[i]++;

}

}

for(i=0; i<11; i++)

{

printf("\n%d: 总数: %d, 哈希链表长度为0的数目: %d\n",

i+1, hash_table[i]->len, sum[i]);

hash_destroy(hash_table+i);

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值