改进hash遍历

STL中实现的hash_map和MFC中实现的CMap数据结构均为hash。普通的hash在遍历时,效率会比较慢。hash_map与CMap的遍历均顺序访问每一个桶,因此会在空桶上浪费一定的时间。

1. 改进的hash

哈希结点结构如图1-1(a)所示,其中data为存储的数据,next为指向下一个哈希结点的指针。哈希头结点如图1-1(b)所示,其中preBucket为前一个有数据的桶号,nextBucket为后一个有数据的桶号,hashNode为指向第一个数据的指针。

图1-1 哈希结点、头结点示意图

由此定义改进的hash如下:

class hash

{

      int first;

      vector<hashHeadNode> hashTable;

};

其中first指向第一个有数据的桶号,vector即一个容器,可当做可扩展数组处理。

2 改进hash操作

2.1 初始化  

hashTable初始化为一个比实际数据大30%的一个素数hash_size,first值为-1表示没有任何元素,任意头结点的hashNode为空,preBucket、nextBucket均为-1表示该桶前后均无数据。

2.2 插入u

(1) keyBucket =u%hash_size;

(2) 创建一个哈希结点HN,令HN.data = u,利用头插法插入到hashTable[keyBucket].hashNode上;

(3) 修改first与hashTable[keyBucket]中的preBucket与nextBucket的值。

2.3 删除元素v

(1) keyBucket =v%hash_size;

(2) 遍历hashTable[keyBucket].hashNode,若找到v则删除。

(3) 修改相应的hashTable[keyBucket]中preBucket、nextBucket的值,且first与keyBucket相同时也应做相应的修改。

2.4 查找w

(1) keyBucket =v%hash_size;

(2) 遍历hashTable[keyBucket].hashNode,若找到w则返回true,否则返回false。

2.5 遍历

(1) first为有数据的桶号;

(2) 遍历完成当前桶(currentBucket),利用hashTable[current]中的nextBucket找到下一个有数据的桶,继续遍历。

3 测试

实际测试数据中遍历会比hash_map、CMap快,查询、插入操作也比hash_map、CMap略快。



### C语言中哈希表的实现与使用 #### 哈希表的基本概念 哈希表是一种数据结构,通过将键映射到固定大小的数据结构(通常是数组)上来实现高效的插入、删除和查找操作。这种映射由哈希函数完成。 #### 插入操作 当向哈希表中插入一个新的键值对时,首先需要计算给定键的哈希值,并将其转换为索引位置。如果发生冲突,则采用特定策略解决。例如,在双散列方法中,会利用第二个哈希函数来决定新的探查间隔[^2]: ```c int insert_into_hash_table(HashTable* ht, int key, void* value){ int index = hash_function(key); if(ht->table[index].status == EMPTY || ht->table[index].key == key){ /* 如果为空或者已经存在 */ // 执行插入逻辑... } } ``` #### 删除操作 要从哈希表里移除某个元素,同样先定位其所在的位置;需要注意的是,为了保持后续查找功能正常运作,通常不会真正清除掉该项的空间占用,而是标记它为已删除状态。 #### 查找操作 对于查找请求而言,依据提供的关键字再次调用相同的哈希算法得出目标可能存在的下标,之后沿着链路遍历直至发现匹配项或确认不存在为止。 #### 键值对封装 可以定义一个`Pair`结构体用于保存每一对关联起来的关键字及其对应的数值[^3]: ```c typedef struct { int key; int *val; } Pair; // 创建新节点并初始化成员变量 Pair create_pair(int k, int v) { Pair p; p.key = k; p.val = malloc(sizeof(*p.val)); *(p.val) = v; return p; } ``` #### 解决碰撞的方法之一——开放寻址法之二次探测再散列技术 此方式基于线性探测改进而来,区别在于每次遇到占据位子的情况时不简单加一移动,而是按照一定规律跳跃前进,具体公式如下所示: \[ \text{{new\_position}}=(\text{{original\_pos}}+i\times s)\mod{\text{{TABLE_SIZE}}} \] 这里\(s\)代表步长增量,一般取较小质数以减少聚集现象的发生概率.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值