算法:哈希表格(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)
随机推荐
- Java之反转排序
顾名思义,反转排序就是以相反的顺序把原来的数组内容重新进行排序.反转排序算法在我们的程序开发中也是经常用到的.而反转排序的基本思想也很简单,就是把数组最后一个元素与第一个元素进行交换,倒数第二个与第二 ...
- mysqlsla 安装
tar -zxvf mysqlsla-2.03.tar.gz cd mysqlsla-2.03 perl Makefile.PLmake && make install BEGIN f ...
- Abstract Factory 抽象工厂
意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 一个系统要独立于它的产品的创建.组合和表示时 结构 参与者 AbstractFactory:声明一个创建抽象产品对象 ...
- 003 Ajax中传输格式为XML
一: 1.优缺点 二:大纲 1.结构设计 三:程序 1.xml <?xml version="1.0" encoding="utf-8"?> < ...
- Ionic入门十:icon(图标)
ionic 也默认提供了许多的图标,大概有500多个.用法也非常的简单: <i class="icon ion-star"></i> 图标列表如下:   ...
- react篇章-React Props-Props 验证
React.PropTypes 在 React v15.5 版本后已经移到了 prop-types 库. <script src="https://cdn.bootcss.com/pr ...
- Java_正则表达式&时间日期
正则表达式 1.概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符合某个句法规则 ...
- JAVAEE——宜立方商城02:服务中间件dubbo、工程改造为基于soa架构、商品列表实现
1. 学习计划 第二天:商品列表功能实现 1.服务中间件dubbo 2.工程改造为基于soa架构 3.商品列表查询功能实现. 2. 将工程改造为SOA架构 2.1. 分析 由于宜立方商城是基于soa的 ...
- 第1天:Django框架简介与工程创建
Django简介 Django特点 环境搭建 创建工程 启动服务 使用pycharm打开工程 创建子应用 Django简介 Django,是用Python语言写的开源web开发框架,并遵循MVC设计. ...
- 将已有的项目提交到GitHub
1.目的: 将已有的项目提交到GitHub 2.准备工作 2.1 此教程建立在对git有初步的理解上 2.2 此教程之前需准备工作 a.熟悉git的一些基本命令和原理. b.已注册有GitHub账号. ...