数据结构Hash--开放定址法

Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数
开放定制法也是处理构造哈希表中关键字的哈希地址冲突的一种有效方法。
开放定址法就是从发生冲突的那个单元开始,按照一定的次序,从哈希表中查找出一个空闲的存储单元,把发生冲突的待插入元素存入到该空闲单元的一类处理冲突的方法。在开放定址法中,哈希表中的空闲单元(假定下标为i)不仅向哈希地址为i的同义词的元素开放,允许它们使用,也向发生冲突的其他元素开放,因它们 的哈希地址不为i,所以称之为非同义词元素。
总之,在开放定址法中,空闲单元不仅向同义词开放,也向发生冲突的非同义词开放,因此称之为开放定址法。
假设哈希表的地址集为0~n-1,冲突是指关键字得到的哈希地址为j(0<=j<=n-1)的位置上已经有关键字存在,则冲突处理就是为该关键字找到一个“空”的哈希地址。在处理冲突的过程中可能得到一个一个地址序列,Hi (i=1,2,3,4…k,),Hi介于0到n-1之间,即在处理哈希地址的冲突时,若得到另一个哈希地址H1仍然发生冲突,则再求下一个地址H2,若H2仍然冲突,则再求H3,以此类推,直至Hk不发生冲突为止,则Hk为记录在表中的地址。

开放定址法主要有三种方法,包括线性探测再散列(即线性探测法),二次探测再散列(即平方探测法)和伪随机探测再散列
这里代码实现的是其中的线性探测再散列:
例如在长度为11的哈希表中,已经填入关键字分别为17,60,29的记录(哈希函数为H(key) MOD 11),现有第四个记录,其关键字为38,由哈希函数得到的哈希地址为5,和关键字为60的哈希地址产生冲突;若用线性探测再散列的方法处理时,得到下一个地址为6,仍冲突;再求下一个地址7,仍然冲突;直到哈希地址为8的位置时,得到一个为“空”的位置,处理冲突的过程结束,并将38插入到哈希表中第8号位置。
这里写图片描述

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int KeyType;
typedef int ValueType;

enum Status
{
    EMPTY,//当前为空
    EXITS,//存在数
    DELETE,
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 根据你的要求,我们需要用C语言实现选取哈希函数H(k)=(3k)MOD 11,用开放定址法处理冲突,di=i(i=1,2,3,…)。 首先,我们需要定义一个哈希表结构体,包含两个成员:一个数组和一个整数表示数组的长度。 ```c #define MAX_SIZE 11 typedef struct { int data[MAX_SIZE]; int length; } HashTable; ``` 接下来,我们需要实现哈希函数H(k)=(3k)MOD 11: ```c int hash(int key) { return (3 * key) % MAX_SIZE; } ``` 然后,我们需要实现开放定址法处理冲突。在本例中,我们使用线性探测法,也就是在发生冲突时,依次查看下一个位置,直到找到空闲的位置为止。di=i(i=1,2,3,…)表示依次查看下一个位置。 ```c int linear_probe(int key, int i) { return (hash(key) + i) % MAX_SIZE; } ``` 最后,我们可以实现哈希表的插入和查找操作。插入操作会先计算哈希值,如果该位置已被占用,则通过线性探测法查找下一个空闲位置,直到找到为止。查找操作会先计算哈希值,如果该位置存储的关键字与待查找的关键字相等,则返回该位置的索引;否则通过线性探测法查找下一个位置,直到找到空闲位置或找到相等的关键字为止。 ```c int insert(HashTable *ht, int key) { int i = 0; int j = hash(key); while (ht->data[j] != 0) { i++; j = linear_probe(key, i); if (i == MAX_SIZE) { return -1; } } ht->data[j] = key; ht->length++; return j; } int search(HashTable ht, int key) { int i = 0; int j = hash(key); while (ht.data[j] != key) { i++; j = linear_probe(key, i); if (ht.data[j] == 0 || i == MAX_SIZE) { return -1; } } return j; } ``` 这样,我们就完成了哈希表的实现。你可以用下面的代码测试一下: ```c #include <stdio.h> #define MAX_SIZE 11 typedef struct { int data[MAX_SIZE]; int length; } HashTable; int hash(int key) { return (3 * key) % MAX_SIZE; } int linear_probe(int key, int i) { return (hash(key) + i) % MAX_SIZE; } int insert(HashTable *ht, int key) { int i = 0; int j = hash(key); while (ht->data[j] != 0) { i++; j = linear_probe(key, i); if (i == MAX_SIZE) { return -1; } } ht->data[j] = key; ht->length++; return j; } int search(HashTable ht, int key) { int i = 0; int j = hash(key); while (ht.data[j] != key) { i++; j = linear_probe(key, i); if (ht.data[j] == 0 || i == MAX_SIZE) { return -1; } } return j; } int main() { HashTable ht = {{0}, 0}; int keys[] = {11, 22, 33, 44, 55, 66, 77, 88, 99}; int i, j; for (i = 0; i < 9; i++) { j = insert(&ht, keys[i]); if (j == -1) { printf("Insertion failed: %d\n", keys[i]); } else { printf("Inserted: %d at %d\n", keys[i], j); } } j = search(ht, 44); if (j == -1) { printf("Search failed: %d\n", 44); } else { printf("Found: %d at %d\n", 44, j); } j = search(ht, 100); if (j == -1) { printf("Search failed: %d\n", 100); } else { printf("Found: %d at %d\n", 100, j); } return 0; } ``` 输出应该是: ``` Inserted: 11 at 0 Inserted: 22 at 3 Inserted: 33 at 6 Inserted: 44 at 9 Inserted: 55 at 1 Inserted: 66 at 4 Inserted: 77 at 7 Inserted: 88 at 10 Inserted: 99 at 2 Found: 44 at 9 Search failed: 100 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值