+ -
当前位置:首页 → 问答吧 → 大侠们救命----关于二次探测再散列的C语言实现

大侠们救命----关于二次探测再散列的C语言实现

时间:2010-08-31

来源:互联网

针对开放地址哈希表结构,采用线性探测再散列处理冲突过程中会发生的两个第一个哈希地址不同的记录争夺一个后续哈希地址的“二次聚集”的现象。
例:
用线性探测再散列法处理冲突: Hi = key MOD m; 其中m=10为哈希表长度,插入前15,16,17,18,19的H(key)分别为:5,6,7,8,9存放地址为:5,6,7,8,9
46的H(key)为6,发生冲突,连续向下探测4次,出现“二次聚集”的现象.

用二次探测再散列法处理冲突: Hi = (H(key) + di)MOD m; 其中m为哈希表长度,di=12,-12,22,-22,32,....k2(k <=m/2),插入前15,16,17,18,19的H(key)分别为:5,6,7,8,9 存放地址为:5,6,7,8,9  
46的H(key)为6,发生冲突. 用二次探测再散列法解决冲突:  
16+12)%10=(6+1)%10=7,仍然发生冲突.  
26-12)%10=(6-1)%10=5,仍然发生冲突.  
36+22)%10=(6+4)%10=0,不再发生冲突.  
则46放置于位置0。

用二次探测再散列法处理冲突时,查找算法如下:
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <assert.h>

  4. #define MAXSIZE 99999
  5. #define YES 1
  6. #define NO 0
  7. #define HK(key) ((key)%(MAXSIZE))

  8. typedef struct uid_e {
  9.         uid_t uid;
  10.         unsigned int njobs;
  11. } uid_e_t;

  12. typedef struct uid_hash {
  13.         uid_e_t elem[MAXSIZE];
  14.         int used[MAXSIZE];
  15. } uid_hash_t;

  16. void init_uid_hash (uid_hash_t *H) {
  17.         assert (H != NULL);
  18.         int i = 0;
  19.         for (i = 0; i < MAXSIZE; i++) {
  20.                 H->elem[i].uid = 0;
  21.                 H->elem[i].njobs = 0;
  22.                 H->used[i] = NO;
  23.         }
  24. }
  25. int insert_uid_hash(uid_hash_t *H, const uid_e_t *e) {
  26.         assert (H != NULL);
  27.         assert (e != NULL);

  28.         unsigned int key = HK(e->uid);
  29.         int di = 1;
  30.         if (H->elem[key].uid == e->uid && H->used[key] == YES ) {
  31.                 return -1;
  32.         }
  33.         while (H->used[key] == YES) {
  34.                //这里输出key
  35.                 printf ("%u\n", key);
  36.                 if (di > MAXSIZE/2) {
  37.                         return -1;
  38.                 }
  39.                 else if (di > 0) {
  40.                         key= HK(HK(e->uid) + (di*di));
  41.                         di = -di;
  42.                         if (key < 0) key = MAXSIZE + key;
  43.                 } else {
  44.                         key= HK(HK(e->uid) - (di*di));
  45.                         di = -di;
  46.                         di ++;
  47.                         if (key < 0) key = MAXSIZE + key;
  48.                 }

  49.         }
  50.         if (key <= MAXSIZE) {
  51.                 H->elem[key] = *e;
  52.                 H->used[key] = YES;
  53.                 return key;
  54.         }
  55.         return -1;
  56. }
  57. int getpos (const uid_hash_t *H, uid_t uid, uid_e_t *e) {
  58.         unsigned int key = HK(uid);
  59.         int di = 1;
  60.         if (H->used[key] == NO) {
  61.                 return -1;
  62.         } else {
  63.                 while (H->used[key] == NO || H->elem[key].uid != uid) {
  64.                         if (di > MAXSIZE/2) {
  65.                                 return -1;
  66.                         }
  67.                         else if (di > 0) {
  68.                                 key = HK(HK(uid) + (di*di));
  69.                                 di = -di;
  70.                                 if (key < 0) key = MAXSIZE + key;
  71.                         } else {
  72.                                 key = HK(HK(uid) - (di*di));
  73.                                 if (key < 0) key = MAXSIZE + key;
  74.                                 di = -di;
  75.                                 di ++;
  76.                         }
  77.                 }
  78.         }
  79.         *e = H->elem[key];
  80.         return key;
  81. }
  82. int main ()
  83. {
  84.         int i = 0;
  85.         uid_hash_t H;
  86.         //设置所有位置已经使用
  87.         for (i = 0; i < MAXSIZE; i ++) {
  88.                 H.used[i] = YES;
  89.         }
  90.         uid_e_t e1 = {1, 1};
  91.         insert_uid_hash(&H, &e1);

  92.         return 0;
  93. }
复制代码
二次探测再散列公式产生的key值如下:


QUOTE:
[root@hpc-rm c_test]# ./a.out | sort -n |less
0
1
1
1
1
1
1
2
2
2
2
5
5
5
5
7
7
7
7
10
10
10
10
10
10
11



为什么会出现重复的key值呢?是不是我的公式不对?
如果公式正确的话,如何才能产生不重复的key值呢?

有建议说把MAXSIZE改为素数就不会出现重复的key了,但我修改后照样会出现重复的key值?为什么呢?
是我算法不对?

求大侠们指点,项目逼得紧!

作者: syoubin_sai   发布时间: 2010-08-31

作者: syoubin_sai   发布时间: 2010-08-31

相关阅读 更多

热门下载

更多