基于线性探测法的散列表
来源:互联网 发布:淘宝索尼丽驰专卖店 编辑:程序博客网 时间:2024/05/21 14:08
#include <stdio.h>//基于线性探测法的散列表//使用线性探测解决键冲突问题,核心思想就是利用数组空位,当使用//哈希函数计算出数组索引后,开始检测该索引位置是否已经被使用,如//果已经使用,则索引向后递增(如果超出数组索引,则需要进行回绕到//数组起始索引),直到找到空位为止,或者数组空间已全部被使用,无//法再扩冲,由于这里利用的是数组空间,所以通常情况下,需要该数组//支持动态调整数组空间功能,当前简化了这步流程,仅使用静态数组进//行分析。#define TEST_CASE (1)#define MAX_HASH_ENTRY 5typedef struct{ int used; int key; int val;} HASH_ENTRY;HASH_ENTRY hashTableEntrys[MAX_HASH_ENTRY] = {0};int g_hashTableEntryCount = 0;//正整数类型的KEY的散列函数//通常采用除留余法,这里通过对KEY进行求余,使得KEY分布在hashTable//的数组中,同时为了减少键冲突,除数通常选择为素数,比如当前示例//选择为97int hashFunctionForInt(int key){ // M 通常为素数 //hashKey = key % M int hashKey = key % 97; return hashKey;}//计算哈希表数组的索引// 1首先算出hashKey// 2 之后根据当前哈希表数组长度进行求余操作,避免计算出来的hashKey大于// 数组长度,导致出现溢出int hashIndex(int key){ int hashKey = hashFunctionForInt(key); return hashKey % MAX_HASH_ENTRY;}//新增条目//1 当前不支持动态调整数组空间,所以需要检测溢出的隐患//2 进行数组空位查找void put(int key, int val){ int index = hashIndex(key); if ( g_hashTableEntryCount >= MAX_HASH_ENTRY ) { printf("don't put, array full.\r\n"); return; } while ( hashTableEntrys[index].used ) { index = (index + 1) % MAX_HASH_ENTRY; } hashTableEntrys[index].used = 1; hashTableEntrys[index].key = key; hashTableEntrys[index].val = val; g_hashTableEntryCount++;}//查找//这里有3种情况会退出循环//1 没有对应的空位了,即没有找到需要的数组//2 有对应的空位,但键值不是要查找的//3 防止数组出现满的情况,这时候需要进行环绕检测,避免死循环int get(int key){ int val = -1; int index = hashIndex(key); int curGetIndex = index; while ( hashTableEntrys[index].used ) { if ( curGetIndex == index ) { break; } if ( hashTableEntrys[index].key == key ) { val = hashTableEntrys[index].val; break; } index = (index + 1) % MAX_HASH_ENTRY; } return val;}//删除//线性探测法由于在进行查找时,遇到空位则停止,所以在进行删除//时,后面数据的问题,比如当前要删除hashKey = 3,当删除第一个//条目时,第一个位置出现了空洞,此时需要将后面项全部删除并重//新插入,否则后面数据将无法访问。// -------------------------// |3|3|3|3| | | | | | | | |// -------------------------int delete(int key){ int find = 0; int index = hashIndex(key); while ( hashTableEntrys[index].used ) { if ( hashTableEntrys[index].key == key ) { find = 1; break; } index = (index + 1) % MAX_HASH_ENTRY; } if ( find ) { int curDeleteIndex = index; hashTableEntrys[index].used = 0; g_hashTableEntryCount--; index = (index + 1) % MAX_HASH_ENTRY; while ( hashTableEntrys[index].used && (curDeleteIndex != index) ) { put(hashTableEntrys[index].key, hashTableEntrys[index].val); hashTableEntrys[index].used = 0; g_hashTableEntryCount--; index = (index + 1) % MAX_HASH_ENTRY; } } return find ? 0 : -1 ;}void testCase0(){ put(1, 1); put(2, 2); put(3, 3); put(4, 4); put(5, 5); put(6, 6); put(7, 7); printf("find key %d, val %d\r\n", 3, get(3)); printf("find key %d, val %d\r\n", 7, get(7));}void testCase1(){ put(3, 3); put(3, 3); put(3, 3); put(3, 3); put(3, 3); put(3, 3); put(3, 3); delete(3); delete(3); delete(3); delete(3); delete(3); delete(3); delete(3); printf("find key %d, val %d\r\n", 3, get(3));}int main(){ printf("max hashTable entry %d\r\n", MAX_HASH_ENTRY); switch ( TEST_CASE ) { case 0: testCase0(); break; case 1: testCase1(); break; default: break; } return 0;}
0 0
- 基于线性探测法的散列表
- 基于线性探测法的散列表 (c++)
- 这一篇是基于线性探测的散列表
- 散列表--线性探测法
- 散列表2: 基于探测法的散列表
- 11、线性探测法解决散列表碰撞问题
- 平方探测和线性探测解决散列表冲突的区别(优点及缺点)
- 12、线性探测法解决散列表保存字典的碰撞问题
- HashTable哈希表/散列表(线性探测和二次探测)
- 散列表(三):冲突处理的方法之开地址法(线性探测再散列的实现)
- 散列表(三):冲突处理的方法之开地址法(线性探测再散列的实现)
- 开放定址散列表(线性探测法)头文件C语言
- 开放定址散列表(线性探测法)实现文件C语言
- 开放定址散列表(线性探测法(双散列))头文件C语言
- 开放定址散列表(线性探测法(双散列))实现文件C语言
- 再散列--开放定址散列表(线性探测法)加强版可再散列经优化头文件C语言
- 再散列开放定址散列表(线性探测法)加强版可再散列经优化实现文件C语言
- 建立Hash表(散列表)(运用线性探测法解决冲突)
- C语言的函数
- Node.js开发入门—使用AngularJS
- 如何安装g++/gdb
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- 基于拉链法的散列表
- 基于线性探测法的散列表
- C语言内存分配
- 条件编译
- 选择法和冒泡法排序接口
- Leetcode#28||Implement strStr()
- 黑马程序员--JAVA基础语法之--关键字、常亮、变量、标识符
- 8.12学习总结
- 进程与线程、应用程序域关系
- WebView的高级用法