• hash表


    1.基本概念

    给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数

    2.hash冲突

    比如

    f(x) = x % 5;          //哈希函数

    int hashTble[5];     //哈希表

    int value[5];         //存放数据的数组

    1. 先忘value[0]存入 'A' [对应ascii码为65] ,  value[1]存入'F' [对应ascii码为70]
    2. f(65) = 0;  那么hashTable[0] = 0;
    3. f(70) = 0; 那么hashTable[1] = 0;

    这就产生了冲突 (hanhTable的0和1是指向的一样的位置)

    • 解决方法:让存入hash表的值不一样

    3.hash的简单实现

    需要实现以下几个接口:

    • struct hash *hash_create(void);     //创建一个hash表

    • void hash_destroy(struct hash *ht);    //销毁hash表

    • int hash_insert(struct hash *ht, const char* key, void *data); //在hash表ht插入一个元素(key, data)

    • void *hash_lookup(struct hash *ht, const char* key);  //在hash表ht中,通过key得到value的指针

    以下摘自linuxptp的hash实现

    1. /**
    2. * @file hash.c
    3. * @brief Implements a simple hash table.
    4. * @note Copyright (C) 2015 Richard Cochran
    5. *
    6. * This program is free software; you can redistribute it and/or modify
    7. * it under the terms of the GNU General Public License as published by
    8. * the Free Software Foundation; either version 2 of the License, or
    9. * (at your option) any later version.
    10. *
    11. * This program is distributed in the hope that it will be useful,
    12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    14. * GNU General Public License for more details.
    15. *
    16. * You should have received a copy of the GNU General Public License along
    17. * with this program; if not, write to the Free Software Foundation, Inc.,
    18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    19. */
    20. #include
    21. #include
    22. #include "hash.h"
    23. #define HASH_TABLE_SIZE 200
    24. struct node {
    25. char *key;
    26. void *data;
    27. struct node *next;
    28. };
    29. struct hash {
    30. struct node *table[HASH_TABLE_SIZE];
    31. };
    32. static unsigned int hash_function(const char* s)
    33. {
    34. unsigned int i;
    35. for (i = 0; *s; s++) {
    36. i = 131 * i + *s;
    37. }
    38. return i % HASH_TABLE_SIZE;
    39. }
    40. //创建hash表
    41. struct hash *hash_create(void)
    42. {
    43. struct hash *ht = calloc(1, sizeof(*ht));
    44. return ht;
    45. }
    46. //清除hash表
    47. void hash_destroy(struct hash *ht, void (*func)(void *))
    48. {
    49. unsigned int i;
    50. struct node *n, *next, **table = ht->table;
    51. for (i = 0; i < HASH_TABLE_SIZE; i++) {
    52. for (n = table[i] ; n; n = next) {
    53. next = n->next;
    54. if (func) {
    55. func(n->data);
    56. }
    57. free(n->key);
    58. free(n);
    59. }
    60. }
    61. free(ht);
    62. }
    63. //向hash表插入元素
    64. int hash_insert(struct hash *ht, const char* key, void *data)
    65. {
    66. unsigned int h;
    67. struct node *n, **table = ht->table;
    68. // 通过hash函数,得到key对应的value【value是hash表的位置下标】
    69. h = hash_function(key);
    70. //避免得到的value值
    71. for (n = table[h] ; n; n = n->next) {
    72. if (!strcmp(n->key, key)) {
    73. /* reject duplicate keys */
    74. return -1;
    75. }
    76. }
    77. //为插入的新元素(链表节点)分配内存
    78. n = calloc(1, sizeof(*n));
    79. if (!n) {
    80. return -1;
    81. }
    82. //为链表节点赋值
    83. n->key = strdup(key);
    84. if (!n->key) {
    85. free(n);
    86. return -1;
    87. }
    88. n->data = data;
    89. n->next = table[h];
    90. //将这个新元素的内存地址存入hash表
    91. table[h] = n;
    92. return 0;
    93. }
    94. //通过key在hash表ht中得到data
    95. void *hash_lookup(struct hash *ht, const char* key)
    96. {
    97. unsigned int h;
    98. struct node *n, **table = ht->table;
    99. h = hash_function(key);
    100. for (n = table[h] ; n; n = n->next) {
    101. if (!strcmp(n->key, key)) {
    102. return n->data;
    103. }
    104. }
    105. return NULL;
    106. }

    比较关键的逻辑就是:hash_insert函数,主要分为几步

    1. 通过hash_function()得到key对应的value,即在hashTable的位置
    2. 把传入的key,data存入一个node
    3. 把hashTable[value]赋值为node的内存地址

    通过hash_lookup()找到key对应的data

    1. 先通过hash_function()算出value,即在hashTable的位置
    2. 通过hashTable[value],找到key对应的那个node
    3. 通过node可找到key对应的data
    4. 返回data作为hash_lookup()的返回值
  • 相关阅读:
    基于SSM的车库智能管理平台设计与实现
    记录字节跳动前端面试,四轮技术面
    苹果 MacBook如何取消开盖自动开机功能?
    R绘制世界统计地图——猴痘最新数据
    研发效能|Kubernetes核心技术剖析和DevOps落地经验
    实验室(检验科)信息系统源码,医学检验LIS系统源码,云LIS源码
    拼多多店铺营业执照相关问题
    Android高通 8.1 老化apk打开摄像头花屏问题
    【嵌入式开发工具】STM32+Keil实现软件工程搭建与开发调试
    服务器(I/O)之多路转接
  • 原文地址:https://blog.csdn.net/m0_37844072/article/details/126277137