项目地址:  https://github.com/kelin-xycs/HashTableLib

为什么会想要自己写一个 Hash 表, 以前也想过 Hash 表 的 原理, 觉得很神奇,

不过最近的 直接原因 是 最近在搞  ILBC, 这可以认为是一个 编译器 项目,

有关 ILBC,  见 《ILBC 规范》  https://www.cnblogs.com/KSongKing/p/10354824.html ,

编译器 里 会 需要 快速 的 查找 成员(变量 、字段 、类 、 方法 / 函数),  比如 检验 成员 是否重名, 以及 对 成员 的 访问 的 编译工作 。

也包括 运行期查找成员(反射 / 动态链接)  。

当然 ILBC 里使用的 Hash 表 会用 C 语言 写, 这次写的 项目 是 用 C# 写的, 在 原理 上 实现了一下 。

具体的逻辑 看代码 就行, 代码不多, 大约 350 行 。  ^^

不过有一点说明一下, 就是可以调用 HashTable 的

public HashTable(int initCapacity)

这个 构造函数 重载 来 指定    initCapacity ,

也可以调用

public HashTable(int initCapacity, double whenEnlarge, double enlargeRatio)

这个 构造函数 重载 来 指定    initCapacity,  whenEnlarge,  enlargeRatio ,

initCapacity  表示 new HashTable  时 的 初始 的 Hash 表 容量,  容量 是指 Hash 表 内部 存储元素 的 数组 的 长度,

whenEnlarge  表示 当 元素(键值对) 的 数量 达到  容量 的 百分之几 时, 要对 Hash 表 扩容(增大容量), 扩容 就是 按照 新的 容量 申请一个 数组, 把 原来的 数组 的 元素 重新 添加到 新数组 里, 注意 这里的 添加 不是 简单的复制, 而是 把  元素(键值对) 重新 添加(Add) 到 Hash 表, 在 添加(Add) 时 会 重新计算 key 的 Hash 值 并 根据 key 的 Hash 值 计算 键值对 在 数组 里的 位置(下标 ( index )) 。

enlargeRatio  表示 扩容 时 要 扩大多少, 即 增加的容量 相对于 原来的容量 所占 的 百分比 。

如果不想自己指定   initCapacity,  whenEnlarge,  enlargeRatio ,    也可以调用 无参 构造函数

public HashTable()

无参 构造函数 使用 默认的   initCapacity,  whenEnlarge,  enlargeRatio ,

initCapacity 的 默认值 是 100 ,

whenEnlarge 的 默认值 是 0.8 ,

enlargeRatio 的 默认值 是 0.3  。

如果 知道 元素(键值对) 的 数量 或者 大概数量, 可以 指定  InitCapacity ,  这样可以 避免 或 减少 扩容 , 提高效率 。

注意 如果 指定 Capacity 是 100,  whenEnlarge 是 0.8, 那么 当 元素(键值对) 数量 达到  100 * 0.8 = 80  后, 再 添加 键值对 时, 就会 扩容 。

现在的设计 只涉及到 扩容, 没有 “缩容”,  缩容 是指 当 元素(键值对) 数量 减少到 一定程度 时, 会 减少 Capacity ,  把 元素(键值对) 放到一个 长度更小 的 数组 里  。

缩容 的 部分 可以仿照 扩容 来写,   但要注意  whenDeLarge 和 whenEnlarge  之间 应该要有 显著 的 差距,  如果 两者 相等 或者 相近,  可能会  刚 扩容 又 缩容,  刚 缩容 又 扩容,  频繁 扩容 缩容 导致 性能低下  。

不过 一般场合 好像 不需要 缩容  。

自己写一个 Hash 表的更多相关文章

  1. 用node.js给C#写一个数据表的实体类生成工具

    虽然微软提供了T4模板,但是我感觉非常难用.哪儿比得上直接用脚本来写模板来的爽. 因为要给一个老项目做周边的工具,需要连接到数据库. 我习惯性用EntityFrameworkCore来做,因为毕竟从出 ...

  2. 计蒜客 成绩统计 (Hash表)

    链接 : Here! 思路 : 如果用 $STL$ 的 $map$ 或者是使用 $unordered\underline{}map$ 的话是会 $T$ 的, 所以得手写一个 $hash表$. 其实这个 ...

  3. 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)

    写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...

  4. 【数据结构】非常有用的hash表

        这篇博客的目的是让尚未学会hash表的朋友们对hash表有一个直观的理解,并且能根据本文定义出属于自己的第一个hash表,但算不上研究文,没有深究概念和成功案例.         什么是has ...

  5. nyist oj 138 找球号(二)(hash 表+位运算)

    找球号(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描写叙述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中.每一个球上都有一个整数编号i(0<=i< ...

  6. Hash表的扩容(转载)

    Hash表(Hash Table)   hash表实际上由size个的桶组成一个桶数组table[0...size-1] . 当一个对象经过哈希之后.得到一个对应的value , 于是我们把这个对象放 ...

  7. LeetCode169:Majority Element(Hash表\位操作未懂)

    题目来源: Given an array of size n, find the majority element. The majority element is the element that ...

  8. 简单好用的hash表-----uthash

    在软件开发中,不可不免的会使用到hash表,hash表的优点这里就不说了,以下介绍一个hash表的C实现, uthash是用宏实现的,使用的时候非常方便,只用包含uthash.h即可. Uthash的 ...

  9. Linux-c glib库hash表GHashTable介绍

    百度云glib  链接:https://pan.baidu.com/s/1W9qdlMKWRKIFykenTVuWNQ 密码:ol6y hash表是一种提供key-value访问的数据结构,通过指定的 ...

随机推荐

  1. 亲自打造Deferred对象

    经过对比之后,决心学习jQuery,自己打造一个Deferred对象.var util = require('./util.js');function Callbacks() { var list = ...

  2. RDP服务开启

    一.RDP协议概述 远程桌面协议(RDP, Remote Desktop Protocol)是一个多通道(multi-channel)的协议,让用户(客户端或称“本地电脑”)连上提供微软终端机服务的电 ...

  3. 解决Gephi导入csv文件时提示“边表格需要一个包含节点标号‘源’和‘目标’列” 问题的两个方案

    1.将csv文件在Excel中打开,并重新保存为csv. 2.将csv文件导入到sqlite,使用sqlite作为数据来源. 标准格式如下

  4. 记一下JavaScript的几种排序算法

    零.写在最前 排序的方法有很多种,这篇文章只是记录我熟悉的算法: 我发现了一个关于排序算法很有趣的网站,把相关的算法演示做成了动画,有兴趣的同学可以看看! 附上SortAnimate网站链接:http ...

  5. vue-router beforeEach死循环

    vue中页面跳墙处理 页面跳墙中使用 vue-router中的 beforeEach的死循环问题 问题展现 import Router from 'vue-router' const router = ...

  6. vscode settings.json

    // 快捷键设置 keyiing.json // 将键绑定放入此文件中以覆盖默认值 [ /* // 转换大写 { "key" : "ctrl+shift+u", ...

  7. Eclipse 手动增加linker library

    多个cu文件nvcc -cubin -m64 -lcudadevrt -lcublas_device -gencode arch=compute_35,code=sm_35 -o test.cubin ...

  8. Sonya and Robots(CodeForces 1004C)

    Since Sonya is interested in robotics too, she decided to construct robots that will read and recogn ...

  9. Visual Basic 2017 操作Excel和word【2】持续更新……

    1.控制台程序创建Excel,并设置状态栏显示“Hello World”文本 Module Module1 Private exitXL As Boolean = False Dim WithEven ...

  10. 如何在Linux上清理内存缓存、缓冲与交换空间

    如何在Linux上清理内存缓存.缓冲与交换空间 与其他类型的操作系统一样,GNU/Linux已经有效的实现了内存管理,甚至更加优秀.但是如果任何进程正在吃光你的内存,并且你想清理它,Linux提供了一 ...