https://gitee.com/linwt0/jsds

哈希函数

设计

  1. 将字符串转换成比较大的数字,这个数字称为 hashCode
  2. 将大的数字压缩到数组(size) 范围之内既 index

    公式

    hashCode = hashCode PRIME_NUMBER + key.charCodeAt(i);
    取余操作:hashCode % size;(霍纳法则)
    PRIME_NUMBER 为质数,且小于数组的容量
    size为哈希表的长度 ```javascript function hasFunc(str, size = 7) { // 质数 const PRIME_NUMBER = 37; // 定义hasCode变量 let hasCode = 0; // 霍纳算法,来计算hasCode的值 for (let i = 0; i < str.length; i++) { hasCode = PRIME_NUMBER
    hasCode + str.charCodeAt(i); } // 取余操作 return hasCode % size; }

console.log(hasFunc(“aa”, 7)); console.log(hasFunc(“AA”, 7)); console.log(hasFunc(“bb”, 7)); console.log(hasFunc(“BB”, 7));

  1. <a name="htb2k"></a>
  2. # 哈希表
  3. ```javascript
  4. class HasTable {
  5. constructor() {
  6. this.storage = [];
  7. this.count = 0;
  8. this.limit = 7;
  9. }
  10. //哈希函数
  11. hasFunc(str, size = 7) {
  12. // 质数
  13. const PRIME_NUMBER = 37;
  14. // 定义 hasCode 变量
  15. let hasCode = 0;
  16. // 霍纳算法,来计算hasCode的值
  17. for (let i = 0; i < str.length; i++) {
  18. hasCode = PRIME_NUMBER * hasCode + str.charCodeAt(i);
  19. }
  20. // 取余操作
  21. return hasCode % size;
  22. }
  23. // 插入修改操作
  24. put(key, value) {
  25. // 根据Key获取index
  26. let index = this.hasFunc(key, this.limit);
  27. // 根据index取出对应的bucket
  28. let bucket = this.storage[index];
  29. // 判断bucket是否为null
  30. if (bucket == null) {
  31. bucket = [];
  32. this.storage[index] = bucket;
  33. }
  34. // 判断是否修改数据
  35. for (let i = 0; i < bucket.length; i++) {
  36. let tuple = bucket[i];
  37. if (tuple[0] === key) {
  38. tuple[1] = value;
  39. return;
  40. }
  41. }
  42. // 添加操作
  43. bucket.push([key, value]);
  44. this.count++;
  45. }
  46. // 获取操作
  47. get(key) {
  48. // 根据key获取index
  49. const index = this.hasFunc(key, this.limit);
  50. // 根据index获取对应的bucket
  51. const bucket = this.storage[index];
  52. // 判断bucket是否空
  53. if (bucket === null) {
  54. return null;
  55. }
  56. // 有bucket那么进行线性查找
  57. for (let i = 0; i < bucket.length; i++) {
  58. let tuple = bucket[i];
  59. if (tuple[0] === key) {
  60. return tuple[1];
  61. }
  62. }
  63. // 没有找到,那么返回Null
  64. return null;
  65. }
  66. // 删除操作
  67. remove(key) {
  68. // 根据key获取index
  69. const index = this.hasFunc(key, this.limit);
  70. // 根据index获取对应的bucket
  71. const bucket = this.storage[index];
  72. // 判断bucket是否空
  73. if (bucket === null) {
  74. return null;
  75. }
  76. // 有bucket那么进行线性查找,并且删除
  77. for (let i = 0; i < bucket.length; i++) {
  78. let tuple = bucket[i];
  79. if (tuple[0] === key) {
  80. bucket.splice(i, 1);
  81. this.count--;
  82. return tuple[1];
  83. }
  84. }
  85. // 没有找到,那么返回Null
  86. return null;
  87. }
  88. // 判断哈希表是否为空
  89. isEmpty() {
  90. return this.count === 0;
  91. }
  92. // 获取哈希表元素个数
  93. size() {
  94. return this.count;
  95. }
  96. }
  97. const hasTable = new HasTable();
  98. hasTable.put("zhangsan", "张三");
  99. hasTable.put("lisi", "李四");
  100. console.log(hasTable.get("zhangsan"));
  101. console.log(hasTable.get("lisi"));
  102. console.log(hasTable.storage);
  103. hasTable.remove("lisi");
  104. console.log(hasTable.get("lisi"));
  105. console.log(hasTable.storage);