首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

小弟我用C写的哈希(hash)存储,不能有效解决冲突,应该如何样加代码,

2012-09-25 
我用C写的哈希(hash)存储,不能有效解决冲突,应该怎么样加代码,请指教![codeC/C++][/code]#include stdio

我用C写的哈希(hash)存储,不能有效解决冲突,应该怎么样加代码,请指教!
[code=C/C++][/code]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char u1;
typedef unsigned int u4;

#define OrderId_Num 20 //订单的大小20个字节
#define KeyWord_Num 2000000 //关键字的总个数 2000000个

typedef struct OrderValue
{
u1 value[OrderId_Num];
structOrderValue *next;
}OrderValue;

typedef struct Link
{
struct OrderValue *head;
}Link;

typedef struct HashTable
{
Link Table[KeyWord_Num];
}HashTable;

/*
 *哈希表的初始化
 *
 * */
static HashTable *Table_init()
{
HashTable *ht;
ht =(HashTable *)malloc(sizeof(HashTable));

memset(ht,0,sizeof(HashTable));
//printf("ht:%x\n",ht);

if(!ht){
return NULL;
}
return ht;
}
/*
 *订单的初始化
 * */
static OrderValue *Order_init(const char OrderId[])
{
OrderValue *new_order;
new_order = malloc(sizeof(OrderValue));
if(!new_order){
return NULL;
}
strcpy(new_order->value,OrderId);
new_order->next = NULL;
return new_order;
}
/*哈希算法*/
static u4 Hash_Fun(char *arKey, int nKeyLength)
{
  register u4 hash = 5381;
   
   
  for (; nKeyLength >= 8; nKeyLength -= 8) {
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  }
  switch (nKeyLength) {
  case 7: hash = ((hash << 5) + hash) + *arKey++;
  case 6: hash = ((hash << 5) + hash) + *arKey++;
  case 5: hash = ((hash << 5) + hash) + *arKey++;
  case 4: hash = ((hash << 5) + hash) + *arKey++;
  case 3: hash = ((hash << 5) + hash) + *arKey++;
  case 2: hash = ((hash << 5) + hash) + *arKey++;
  case 1: hash = ((hash << 5) + hash) + *arKey++; break;
  case 0: break;
  default: break;
  }
   
  return hash;
}
/* ht:Table hash:the value of hash OrderId: The ID of order */
int Insert_Table(HashTable *ht,char *arKey,int nKeyLength, const char OrderId[])
{
OrderValue *new_order;
new_order = Order_init(OrderId);

u4 hash = Hash_Fun(arKey,nKeyLength)/KeyWord_Num;
printf("%s %u\n",arKey,hash);

if( ht->Table[hash].head == NULL){
//接收新的订单;
//printf("***\n");
ht->Table[hash].head = new_order;
printf("Insert new order success : %s \n",ht->Table[hash].head->value);
}//没有冲突 直接放入
else{

new_order->next = ht->Table[hash].head->next; 
ht->Table[hash].head->next = new_order;
printf("Insert link success \n");
//printf("The first order %s\n",ht->Table[hash].head->value);
//将新订单挂在链表上 头插法
}//有冲突 挂在链表上

return 1;
}
/*查找函数*/
OrderValue *Find_Key(HashTable *ht,char *arKey,int nKeyLength)
{
u4 hash = Hash_Fun(arKey,nKeyLength)/KeyWord_Num;

while(ht->Table[hash].head != NULL)
{
//printf("find order :%s\n",ht->Table[hash].head->next->value);
return ht->Table[hash].head;
}

return NULL;
}


int main()
{
HashTable *ht;


ht = Table_init();
char keyword[30] = "%AC%DF%AE%FE%AE";
char keyword2[30] = "%AC%DF%AE%FE%AF";
char order1[OrderId_Num] = "1";
char order2[OrderId_Num] = "2";
char order3[OrderId_Num] = "3";

//u4 hash = Hash_Fun(keyword,strlen(keyword))/KeyWord_Num;
//printf("%u\n",hash);
OrderValue *receive_order;


Insert_Table(ht,keyword,strlen(keyword),order1);
Insert_Table(ht,keyword2,strlen(keyword),order2);
Insert_Table(ht,keyword,strlen(keyword),order3);
Insert_Table(ht,keyword2,strlen(keyword),order3);

receive_order = Find_Key(ht,keyword,strlen(keyword));
OrderValue *tmp = receive_order;
while(tmp != NULL)
{
printf("receive_order is %s\n",tmp->value);
tmp = tmp->next;
}

return 0;
}


如上,比如我的输入关键字为keyword和keyword2, 这样我搜索出来的订单就与我想要的不一样了,看了看hasnh值是一样的,我不清楚这种概率究竟有多大,本来想存储这些关键字的,但出于效率的考虑,我不想用这样。。。还有别的方法吗,最好能给出详细的方法或代码,谢谢啦!!o(∩_∩)o

[解决办法]
我认为必须存放关键字,因为没有办法保证键值绝对不冲突

热点排行