算法:哈希表格(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)
随机推荐
- ES按资源类型统计个数
一.目标:统计各类型资源的个数,输出详细报表 http://10.10.6.225:9200/dsideal_db/t_resource_info/ _mapping { "propert ...
- SQL之DELETE
在SQL中DELETE语句用于删除表中的行. 语法 1.删除特定行 DELETE FROM 表名称 WHERE 列名称 = 值 2.删除所有行:在不删除表的情况下删除所有的行.删除之后表的结构.属性和 ...
- mongo blancer
在 sharded cluster 体系结构中,Balancer 进程的作用是转移数据,当一个 shard 中的数据比其它 shard 的数据多并达到一定条件时,Balancer 进程触发. 为了减少 ...
- 实现nlp文本生成中的beam search解码器
自然语言处理任务,比如caption generation(图片描述文本生成).机器翻译中,都需要进行词或者字符序列的生成.常见于seq2seq模型或者RNNLM模型中. 这篇博文主要介绍文本生成解码 ...
- 2015 icpc北京赛区 D 最小割
题目大意:给你一棵技能树,如果要学习一个技能,那么它之前的技能要全部学完,第 i 个点需要ai 能学习 每条边有一个消耗c 如果支付c那么就能去掉这条边, 你还可以kejin 花费di 就能直接学习 ...
- HDU 1028 HDU 1398 (母函数)
题意:输入一个n 给出其所有组合数 如: 4 = 4; 4 = 3 + 1; 4 = 2 + 2; 4 = 2 + 1 + 1; 4 = 1 + 1 + 1 + 1; 重复不算 母函数入门题 ...
- 【转】关于Jmeter3.0,你必须要知道的5点变化
2016.5.18日,Apache 发布了jmeter 3.0版本,本人第一时间上去查看并下载使用了,然后群里或同事都会问有什么样变化呢?正好在网上看到一遍关于3.0的文章,但是是英文的.这里翻译一下 ...
- IOS成长之路-Xcode cannot run using the selected device. 解决办法
PROJECT --> Info --> Deployment Target --> IOS Deployment Target 里面的值 要设置为 <=真机系统版本 TA ...
- 基于Thinkphp3.2的qq第三方oauth认证登录扩展类
基于Thinkphp3.2的qq第三方oauth认证登录扩展类,由于腾讯oauth sdk写的太多,不能与thinkphp和好的结合,最终想法讲腾讯oauth sdk写成tp的扩展类先看代码,将代码保 ...
- FILE operattion
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QMessageBox>#in ...