哈希查找

左手的ㄟ右手 2023-02-13 03:37 27阅读 0赞

哈希查找是一种通过设计所存储数据元素 与其存放地址之间的映射关系(函数关系)来实现高效查找的方法。比如我需要查询一个数460,那么根据先前存储时所采取的映射关系就可以准确地得到460相应的存储地址,从而实现高效查找。这是一个给定自变量的值,通过指定函数关系,得到因变量的值的过程。所谓哈希冲突就是一个因变量出现多个自变量的情况。

传统上我们要在数据集中查找某一个数据,都是遍历它进行一一比对,而哈希查找不会执行遍历,它是寻址访问(查找),所以效率会高很多,不过在存储空间的利用率上就相对低一些。

如果存储的数据元素有重复的情况呢?就是同样的因变量有多个,这又应该怎样处理?

以下是几种常用的存储整型类型数据的哈希函数设计方法。

第一步:设计哈希函数

设数据元素为K,数据元素个数为n,申请的内存单元个数为m

  1. 除留余数法

h(K) = K mod m

理论研究表明,m取1.1n~1.7n之间的一个素数最好。

  1. 直接定址法

不是很好用

  1. 数字分析法

感觉也不是很好用

哈希表设计

  1. typedef enum {Empty, Active, Deleted} KindOfItem;//表项状态的枚举类型
  2. //表项结构体
  3. typedef struct
  4. {
  5. DataType data;
  6. KindOfItem info;
  7. } HashItem;
  8. typedef struct
  9. {
  10. HashItem *ht; //哈希表数组
  11. int tableSize; //数组最大个数
  12. int currentSize; //当前表项个数
  13. }HashTable;//哈希表结构体
  14. //初始化
  15. int Initiate(HashTable *hash, int mSize)
  16. {
  17. hash->tableSize = mSize;
  18. hash->ht = (HashItem *)malloc(sizeof(HashItem)*mSize);
  19. if(hash->ht==NULL) return 0;
  20. else
  21. {
  22. hash->currentSize = 0;
  23. return 1;
  24. }
  25. }
  26. //查找函数
  27. int Find(HashTable *hash, DataType x)
  28. {
  29. int i = x.key % hash->tableSize;
  30. int j = i;
  31. while(hash->ht[j].info == Active && hash->ht[j].data.key != x.key)
  32. //说明存在冲突
  33. {
  34. j = (j + 1)%hash->tableSize;//哈希冲突函数继续查找
  35. if(j==i)//说明已遍历整个哈希表未找到且表已满
  36. return -hash->tableSize;
  37. }
  38. if(hash->ht[j].info == Active) return j;
  39. else return -j;
  40. }
  41. //把数据元素x插入到哈希表hash中
  42. int Insert(HashTable *hash, DataType x)
  43. {
  44. int i = Find(hash, x);
  45. if(i>=0) return 0;
  46. else if(i!= -hash->tableSize)
  47. {
  48. hash->ht[-i].data = x;
  49. hash->ht[-i].info = Active;
  50. hash->currentSize++;
  51. return 1;
  52. }
  53. else return 0;
  54. }
  55. //删除哈希表hash中的数据元素x
  56. int Delete(HashTable *hash, DataType x)
  57. {
  58. int i = Find(hash, x);
  59. if(i>=0)
  60. {
  61. hash->ht[i].info = Deleted;
  62. hash->currentSize--;
  63. return 1;
  64. }
  65. else return 0;
  66. }
  67. //撤销函数
  68. void Destroy(HashTable *hash)
  69. {
  70. free(hash->ht);
  71. }

测试:

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. typedef int KeyType;
  4. typedef struct
  5. {
  6. KeyType key;
  7. }DataType;
  8. #include "head.h"
  9. int main()
  10. {
  11. HashTable myHashTable;
  12. DataType a[] = {180,750,600,430,541,900,460}, item = {430};
  13. int i,j,k,n=7,m=11;
  14. Initiate(&myHashTable,m);
  15. for(i=0;i<n;i++)
  16. {
  17. Insert(&myHashTable,a[i]);
  18. }
  19. for(i=0;i<n;i++)
  20. {
  21. j = Find(&myHashTable,a[i]);
  22. printf("j=%d ht[]=%d\n",j,myHashTable.ht[j].data.key);
  23. }
  24. k = Find(&myHashTable, item);
  25. if(k>=0) printf("查找成功,元素%d的哈希地址为%d\n",item.key,k);
  26. else printf("查找失败\n");
  27. Delete(&myHashTable,item);
  28. k = Find(&myHashTable,item);
  29. if(k>=0) printf("查找成功,元素%d的哈希地址为%d\n",item.key,k);
  30. else printf("查找失败\n");
  31. Destroy(&myHashTable);
  32. return 0;
  33. }

发表评论

表情:
评论列表 (有 0 条评论,27人围观)

还没有评论,来说两句吧...

相关阅读