算法:哈希表格(Hash Table)
背景
Java 和 .Net 平台都有一个所有引用类型都会间接或直接继承的类型:Object,这个类型提供最基本的相等性比较算法和哈希算法,很多书上都给出了在重写这两个算法的时候的主意事项,其中大多数主意事项都和哈希表有关。
《CLR VIA C#》的作者觉得将哈希算法放到 Object 不是很适合,我也有这种感觉,每次重写相等性比较算法都要重新哈希算法,非常不爽,我就没打算将其用到哈希表中作为键使用。
哈希表
定义
使用哈希算法将 A 数值空间(键)映射到 B 数值空间(存储),如下:
A -> 0
B -> 1
C -> 2
D -> 3
B 数值空间的查询速度要求非常快,毫无疑问就是数值了。
冲突
数组的大小是固定,当出现冲突(两个键映射为同一个数值了)的时候如何处理呢?有两种策略:
- 在数组中按照一定的算法继续探测其它地址。
- 在数组的每个元素存储的都是链表,冲突的元素会被插入到链表中。
实现
链表节点
class Node<TKey, TValue>
{
public TKey Key { get; set; } public TValue Value { get; set; } public Node<TKey, TValue> Next { get; set; }
}
链表
class LinkedList<TKey, TValue>
{
public Node<TKey, TValue> First { get; set; } public void Insert(TKey key, TValue value)
{
if (this.Contains(key))
{
throw new InvalidOperationException("不能插入重复的键");
} var node = new Node<TKey, TValue> { Key = key, Value = value };
node.Next = this.First;
this.First = node;
} public void Delete(TKey key)
{
Node<TKey, TValue> parent;
Node<TKey, TValue> node; if (!this.Find(key, out parent, out node))
{
throw new InvalidOperationException("不存在指定的键");
} if (parent == null)
{
this.First = null;
}
else
{
parent.Next = node.Next;
}
} public bool Contains(TKey key)
{
Node<TKey, TValue> parent;
Node<TKey, TValue> node; return this.Find(key, out parent, out node);
} public bool Find(TKey key, out Node<TKey, TValue> node)
{
Node<TKey, TValue> parent; return this.Find(key, out parent, out node);
} public bool Find(TKey key, out Node<TKey, TValue> parent, out Node<TKey, TValue> node)
{
parent = null;
node = this.First; while (node != null)
{
if (node.Key.Equals(key))
{
return true;
} parent = node;
node = node.Next;
} return false;
}
}
哈希表
class HashTable<TKey, TValue>
{
private LinkedList<TKey, TValue>[] _items; public HashTable(int size)
{
_items = new LinkedList<TKey, TValue>[size];
} public void Insert(TKey key, TValue value)
{
var index = this.HashToIndex(key);
if (_items[index] == null)
{
_items[index] = new LinkedList<TKey, TValue>();
} _items[index].Insert(key, value);
} public void Delete(TKey key)
{
var index = this.HashToIndex(key);
if (_items[index] == null)
{
throw new InvalidOperationException("不存在指定的键");
} _items[index].Delete(key);
} public bool Find(TKey key, out TValue value)
{
value = default(TValue); var index = this.HashToIndex(key);
if (_items[index] == null)
{
return false;
} Node<TKey, TValue> node;
var finded = _items[index].Find(key, out node);
if (!finded)
{
return false;
}
else
{
value = node.Value;
} return true;
} private int HashToIndex(TKey key)
{
return key.GetHashCode() % _items.Length;
}
}
备注
哈希算法、负载因子、自动扩容都是需要考虑的,这里就不多说了。
算法:哈希表格(Hash Table)的更多相关文章
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- PHP关联数组和哈希表(hash table) 未指定
PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...
- 算法导论-散列表(Hash Table)-大量数据快速查找算法
目录 引言 直接寻址 散列寻址 散列函数 除法散列 乘法散列 全域散列 完全散列 碰撞处理方法 链表法 开放寻址法 线性探查 二次探查 双重散列 随机散列 再散列问题 完整源码(C++) 参考资料 内 ...
- 词典(二) 哈希表(Hash table)
散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...
- 什么叫哈希表(Hash Table)
散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...
- 数据结构 哈希表(Hash Table)_哈希概述
哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...
- 白话算法(6) 散列表(Hash Table)从理论到实用(上)
处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通过一般化的推理来论证理解,并可归纳成一般公式,而这个一般公式适用于任何特殊 ...
- 白话算法(6) 散列表(Hash Table) 从理论到实用(下)
[澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] ——自扯自蛋 无论开发一个程序还是谈一场恋爱,都差不多要经历这么4个阶段: 1)从零开始.没有束缚的轻松感.似 ...
- 白话算法(6) 散列表(Hash Table)从理论到实用(中)
不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好的)方法.推动科技进步的人,永远是那些敢于问出比外行更天真.更外行的问题, ...
- 哈希表(Hash table)
随机推荐
- python的简介(一)
1. Python的种类 Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚 ...
- 使用ASP.NET MVC+Entity Framework快速搭建系统
详细资料: http://www.cnblogs.com/dingfangbo/p/5771741.html 学习 ASP.NET MVC 也有一段时间了,打算弄个小程序练练手,做为学习过程中的记录和 ...
- ref:Mysql授权远程登陆
ref:https://blog.csdn.net/qq_26710805/article/details/79776897 在Windows环境上操作.步骤如下: 1. 打开cmd窗口,登陆mysq ...
- 有关Virtualbox虚拟机增强功能安装的问题
在老师给定的步骤下并不能正常的完成Virtualbox虚拟机增强功能安装而是显示下图
- 【面试总结】网易2019秋招一站式面试总结(等offer中……)
岗位:运维工程师(网易杭州) 面试时间:一天 上午十一点二十,准时开启面试,初面面试官是个看起来就像是主管的人,厚实的身体,中气浑厚的声音,整齐朴素的衬衫. 简要问题摘录如下:(后续补充答案内容) 1 ...
- CSUOJ 1021 组合数末尾的零 二进制
Description 从m个不同元素中取出n (n ≤ m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数.组合数的计算公式如下: C(m, n) = m!/((m - n)!n! ...
- 世界杯:用Python分析热门夺冠球队-(附源代码)
2018年,火热的世界杯即将拉开序幕.在比赛开始之前,我们不妨用 Python 来对参赛队伍的实力情况进行分析,并大胆的预测下本届世界杯的夺冠热门球队. 通过数据分析,可以发现很多有趣的结果,比如: ...
- python 并集union, 交集intersection, 差集difference, 对称差集symmetric_difference
python的集合set和其他语言类似,是一个无序不重复元素集, 可用于消除重复元素. 支持union(联合), intersection(交), difference(差)和sysmmetric d ...
- ARM 常用汇编指令
ARM 汇编程序的框架结构 .section .data <初始化的数据> .section.bss <未初始化的数据> .section .text .global _sta ...
- 【枚举】AtCoder Regular Contest 095 C - Symmetric Grid
题意:给你一个H*W的字符矩阵,一次操作可以任意将两行或者两列交换.问你是否能通过任意多次操作,使得其变为对称矩阵.对称的含义是:对于任何格子A(i,j),其都等于A(H-i+1,W-j+1). 显然 ...