大侠们救命----关于二次探测再散列的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,发生冲突. 用二次探测再散列法解决冲突:
1
6+12)%10=(6+1)%10=7,仍然发生冲突.
2
6-12)%10=(6-1)%10=5,仍然发生冲突.
3
6+22)%10=(6+4)%10=0,不再发生冲突.
则46放置于位置0。
用二次探测再散列法处理冲突时,查找算法如下:
复制代码
二次探测再散列公式产生的key值如下:
为什么会出现重复的key值呢?是不是我的公式不对?
如果公式正确的话,如何才能产生不重复的key值呢?
有建议说把MAXSIZE改为素数就不会出现重复的key了,但我修改后照样会出现重复的key值?为什么呢?
是我算法不对?
求大侠们指点,项目逼得紧!
例:
用线性探测再散列法处理冲突: 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,发生冲突. 用二次探测再散列法解决冲突:
1

2

3

则46放置于位置0。
用二次探测再散列法处理冲突时,查找算法如下:
- #include <stdio.h>
- #include <sys/types.h>
- #include <assert.h>
-
- #define MAXSIZE 99999
- #define YES 1
- #define NO 0
- #define HK(key) ((key)%(MAXSIZE))
-
- typedef struct uid_e {
- uid_t uid;
- unsigned int njobs;
- } uid_e_t;
-
- typedef struct uid_hash {
- uid_e_t elem[MAXSIZE];
- int used[MAXSIZE];
- } uid_hash_t;
-
- void init_uid_hash (uid_hash_t *H) {
- assert (H != NULL);
- int i = 0;
- for (i = 0; i < MAXSIZE; i++) {
- H->elem[i].uid = 0;
- H->elem[i].njobs = 0;
- H->used[i] = NO;
- }
- }
- int insert_uid_hash(uid_hash_t *H, const uid_e_t *e) {
- assert (H != NULL);
- assert (e != NULL);
-
- unsigned int key = HK(e->uid);
- int di = 1;
- if (H->elem[key].uid == e->uid && H->used[key] == YES ) {
- return -1;
- }
- while (H->used[key] == YES) {
- //这里输出key
- printf ("%u\n", key);
- if (di > MAXSIZE/2) {
- return -1;
- }
- else if (di > 0) {
- key= HK(HK(e->uid) + (di*di));
- di = -di;
- if (key < 0) key = MAXSIZE + key;
- } else {
- key= HK(HK(e->uid) - (di*di));
- di = -di;
- di ++;
- if (key < 0) key = MAXSIZE + key;
- }
-
- }
- if (key <= MAXSIZE) {
- H->elem[key] = *e;
- H->used[key] = YES;
- return key;
- }
- return -1;
- }
- int getpos (const uid_hash_t *H, uid_t uid, uid_e_t *e) {
- unsigned int key = HK(uid);
- int di = 1;
- if (H->used[key] == NO) {
- return -1;
- } else {
- while (H->used[key] == NO || H->elem[key].uid != uid) {
- if (di > MAXSIZE/2) {
- return -1;
- }
- else if (di > 0) {
- key = HK(HK(uid) + (di*di));
- di = -di;
- if (key < 0) key = MAXSIZE + key;
- } else {
- key = HK(HK(uid) - (di*di));
- if (key < 0) key = MAXSIZE + key;
- di = -di;
- di ++;
- }
- }
- }
- *e = H->elem[key];
- return key;
- }
- int main ()
- {
- int i = 0;
- uid_hash_t H;
- //设置所有位置已经使用
- for (i = 0; i < MAXSIZE; i ++) {
- H.used[i] = YES;
- }
- uid_e_t e1 = {1, 1};
- insert_uid_hash(&H, &e1);
-
- return 0;
- }
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
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
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28