hash算法原理本文就不累赘讲述了,百度/google一下就知道了。
本demo程序实现一个简单的联系人hash表,通过姓名查找联系人:
1. hash函数采用简单的姓名字母累加和,通过掩码映射的方式获取hash-key;
2. 冲突解决采用链式散列;
3.由于联系人姓名(拼音)累加和分布相对集中(几百到两千左右),因此该hash表容量一般小于2000冲突较少,如果联系人数量较多,该hash函数冲突会增加。
-
/**
-
* 联系人hash表实现demo
-
*/
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
struct hashtableentry {
-
int flag;
-
int nextindex;
-
int prveindex;
-
char* name;
-
};
-
-
struct peoplehashtable {
-
unsigned int size;
-
unsigned int entrys;
-
struct hashtableentry *datas;
-
};
-
-
enum entryflag {
-
state_unused = 0,
-
state_hash_used,
-
state_collision_used
-
};
-
-
int getuppersize(int size)
-
{
-
int uppersize = 1;
-
-
if (size <= 0)
-
return 1;
-
-
while (uppersize < size)
-
uppersize <<= 1;
-
-
return uppersize;
-
-
}
-
-
int gethashkey(struct peoplehashtable *table, const char *name)
-
{
-
char *ptr;
-
unsigned key = 0;
-
-
if (null == name)
-
return -1;
-
-
ptr = name;
-
-
while ('\0' != *ptr)
-
{
-
key = *ptr;
-
ptr;
-
}
-
-
printf("sum of %s: [%d], and key : [%d]\n",name, key, key & (table->size -1));
-
if (null == table)
-
return key;
-
-
return (key & (table->size -1));
-
}
-
-
int insert2table(struct peoplehashtable *table, char *name)
-
{
-
int key = 0;
-
struct hashtableentry *entry;
-
struct hashtableentry *tmp;
-
-
int i;
-
-
if (null == table)
-
return -1;
-
-
if (table->entrys == table->size)
-
{
-
printf("table is full, can not insert only more!\n");
-
return -1;
-
}
-
-
key = gethashkey(table, name);
-
entry = &(table->datas[key]);
-
-
if (entry->flag == state_unused)
-
{
-
entry->flag = state_hash_used;
-
entry->name = name;
-
table->entrys;
-
return 0;
-
}
-
-
if (entry->flag == state_hash_used)
-
{
-
// find a useable entry
-
for (i = 0; i < table->size; i)
-
{
-
if (table->datas[i].flag == state_unused)
-
break;
-
}
-
-
// find if entry has a collision entry
-
while( entry->nextindex != -1)
-
{
-
entry = &table->datas[entry->nextindex];
-
}
-
-
tmp = &(table->datas[i]);
-
-
tmp->flag = state_collision_used;
-
tmp->name = name;
-
tmp->prveindex = key;
-
-
entry->nextindex = i;
-
table->entrys;
-
return 0;
-
}
-
-
if (entry->flag == state_collision_used)
-
{
-
// find a useable entry
-
for (i = 0; i < table->size; i)
-
{
-
if (table->datas[i].flag == state_unused)
-
break;
-
}
-
-
// remove current entry to the empty entry space
-
tmp = &table->datas[entry->prveindex];
-
tmp->nextindex = i;
-
-
tmp = &table->datas[i];
-
tmp->prveindex = entry->prveindex;
-
tmp->flag = entry->flag;
-
tmp->name = entry->name;
-
tmp->nextindex = entry->nextindex;
-
-
entry->flag = state_hash_used;
-
entry->name = name;
-
entry->prveindex = -1;
-
entry->nextindex = -1;
-
-
table->entrys;
-
return 0;
-
}
-
-
return -1;
-
}
-
-
struct hashtableentry* findpeople(struct peoplehashtable *table, char *name)
-
{
-
int key;
-
struct hashtableentry *entry = null;
-
-
if (null == table)
-
return null;
-
-
key = gethashkey(table, name);
-
-
entry = &table->datas[key];
-
if (entry->name != null && !strcmp(entry->name, name))
-
{
-
return entry;
-
}
-
-
while(entry)
-
{
-
if (entry->name && !strcmp(entry->name, name))
-
return entry;
-
-
if (entry->nextindex != -1)
-
entry = &table->datas[entry->nextindex];
-
else
-
return null;
-
}
-
return null;
-
}
-
-
int createhashtable(struct peoplehashtable **table, unsigned int size)
-
{
-
int uppersize = getuppersize(size);
-
-
struct peoplehashtable *tableptr = null;
-
struct hashtableentry *entrylist = null;
-
int i;
-
-
tableptr = (struct peoplehashtable*)malloc(sizeof(*tableptr));
-
if (null == tableptr)
-
return -1;
-
-
entrylist = (struct hashtableentry*)malloc(sizeof(*entrylist) * uppersize);
-
if (null == entrylist)
-
{
-
free(tableptr);
-
return -1;
-
}
-
memset(entrylist, 0, sizeof(*entrylist) * uppersize);
-
for(i = 0; i < uppersize; i)
-
{
-
entrylist[i].flag = state_unused;
-
entrylist[i].name = null;
-
entrylist[i].nextindex = -1;
-
entrylist[i].prveindex = -1;
-
}
-
-
tableptr->datas = entrylist;
-
tableptr->entrys = 0;
-
tableptr->size = uppersize;
-
-
*table = tableptr;
-
-
return 0;
-
}
-
-
int destoryhashtable(struct peoplehashtable *table)
-
{
-
if (null == table)
-
return 0;
-
-
free(table->datas);
-
free(table);
-
-
return 0;
-
}
-
-
static void debug_print_table(struct peoplehashtable *table)
-
{
-
int i;
-
-
printf("table infos:\n");
-
printf("size: [%d], entry numbers;[%d]\n", table->size,table->entrys);
-
printf("index flag prve next name\n");
-
for (i = 0; i < table->size; i)
-
{
-
printf("]]]] %s\n", i,table->datas[i].flag ,table->datas[i].prveindex, table->datas[i].nextindex, table->datas[i].name == null ? "--" :table->datas[i].name);
-
}
-
}
-
/*
-
void main()
-
{
-
char *peoples[30]= {
-
"刘敏",
-
"wang wu",
-
"li si",
-
"liu yu gu",
-
"jiang jie hui",
-
"tan wei wei",
-
"liu tao",
-
"mi yue",
-
"mi shu",
-
"yin si",
-
"yin dang",
-
"huang zi",
-
"zhang zi",
-
"qu yuan",
-
"tang jia jun",
-
"gui wa zi",
-
"qu li zi",
-
"gong zhu",
-
"tang hui",
-
"jiu zhong",
-
""
-
};
-
-
struct peoplehashtable *table;
-
struct hashtableentry *entry;
-
-
int ret;
-
int i;
-
-
ret = createhashtable(&table, 20);
-
-
if (ret < 0)
-
{
-
printf("create hash table fail\n");
-
return;
-
}
-
-
i = 0;
-
for (i = 0; i < 20; i)
-
{
-
insert2table(table,peoples[i]);
-
}
-
printf("-- add people done!\n");
-
-
debug_print_table(table);
-
-
-
entry = findpeople(table, "jiu zhong");
-
if (entry != null)
-
{
-
printf("find!\n");
-
}
-
else
-
printf("--no--\n");
-
-
destoryhashtable(table);
-
table = null;
-
}*/
阅读(2311) | 评论(0) | 转发(0) |