算法----散列

/*
* 算法——散列
* 散列表是基于数组进行设计的。数组的长度是预先设定的
* 所有元素根据和该元素对应的键,保存在数组的特定位置,该键和我们前面讲到的字典中的键是类似的概念
* 使用散列表存储数据时,通过一个散列函数将键映射为一个数字,这个数字的范围是 0 到散列表的长度。
*
* 这里所说的键 应该就是数组的索引 只不过 数组既然长度确定了,那么索引的个数也是确定了
* 每个元素是无限的,每个元素的键值映射出来的索引也许就会发生重复或说碰撞。 这个叫有效碰撞。
*
* 键值映射到数组的索引 这个过程是由散列函数来完成。 散列函数的选择 要保证键值映射出来的索引是尽量不重复的
*
* simpleHash: 散列函数
*
* put: 在散列中增加元素
*
* showDistro: 展示散列中的元素
* */
function simpleHash(data) {
    var total = 0;
    for(var i = 0 ; i < data.length; i++) {
        total += data.charCodeAt(i);
    }
    return total % this.table.length;
}
function put(data) {
    var pos = this.simpleHash(data);
    this.table[pos] = data;
}
function showDistro() {
    for(var i = 0 ; i < this.table.length;i++) {
        if (this.table[i] !== undefined) {
            console.log(i + ":" +this.table[i])
        }
    }
}
function HashTable() {
    this.table = new Array(137);
    this.buildChains = buildChains;
    this.simpleHash = simpleHash;
    this.put = put;
    this.showDistro = showDistro;
}
var someNames = ["David", "Jennifer", "Donnie", "Raymond",
    "Cynthia", "Mike", "Clayton", "Danny", "Jonathan"],
    h = new HashTable();
// h.buildChains();  //测试线性探测法 注释掉
for (var i = 0; i< someNames.length;i++) {
    h.put(someNames[i]);
}
h.showDistro(); // 输出:35: Cynthia 45: Clayton 57: Donnie 77: David 95: Danny 116: Mike 132: Jennifer 134: Jonathan

//是输出了8位少了一位? 记得上面的说明 散列函数可能会映射相同的索引出来 出现了有效碰撞。

//更好的散列函数 数组长度是质数 计算过程中再乘以一个质数

//为什么要选择一个质数呢? 质数特点:只有1 和 本身两个因数 而合数 有两个以上因数 如果除余合数 那么造成重复机会大
//因为合数有多个因子 比如 20   50%20 70%20 是一样的

//感觉这个质数不是特别靠谱 ^^ 下面有其它方法解决

function simpleHash(data) {
    const H = 5;
    var total = 0;
    for (var i = 0; i < data.length; ++i) {
        total += H * total + data.charCodeAt(i);
    }
    return total % this.table.length;
}

/*碰撞处理
* 1、开链法:开链法是指实现散列表的底层数组中,每个数组元素又是一个新的数据结构,比如另一个数组,这样就能存储多个键了
* 2、线性探测法 线性探测法检查散列表中的下一个位置是否为空。如果为空,就将数据存入该位置;如果不为空,则继续检查下一个位置,直到找到一个空的位置为止
* */
/*
* 两个方法该如何选择?
* 当存储数据使用的数组特别大时,选择线性探测法要比开链法好。这里有一个公式,常常
 可以帮助我们选择使用哪种碰撞解决办法:如果数组的大小是待存储数据个数的 1.5 倍,
 那么使用开链法;如果数组的大小是待存储数据的两倍及两倍以上时,那么使用线性探
 测法。
* */
/*下面这些方法是对上面的方法重新或新增*/

/*开链法*/

function buildChains() {
    for(var i = 0; i < this.table.length;i++) {
        this.table[i] = new Array();
    }
}
// function showDistro() {
//     for(var i = 0 ; i < this.table.length;i++) {
//         if (this.table[i][0] !== undefined) {
//             console.log(i + ":" +this.table[i])
//         }
//     }
// }
// function put(data) {
//     var pos = this.simpleHash(data);
//     this.table[pos].push(data);
// }

/*线性探测法*/

function put(data) {
    var pos = this.simpleHash(data);
    while (this.table[pos] !== undefined) {
        pos++;
    }
    this.table[pos] = data;
}

原文地址:https://www.cnblogs.com/yunnex-xw/p/9869993.html

时间: 2024-08-30 06:12:08

算法----散列的相关文章

JavaScript数据结构与算法-散列练习

散列的实现 // 散列类 - 线性探测法 function HashTable () { this.table = new Array(137); this.values = []; this.simpleHash = simpleHash; this.betterHash = betterHash; this.showDistro = showDistro; this.put = put; this.get = get; } function put (key, data) { let pos

数据结构与算法----散列/哈希

1. 简介 散列表的实现叫散列hashing,散列用于以常数平均时间执行 插入.删除.查找,不支持排序.findMin.findMax. 查找关键字不需要 比较 在一个记录的存储位置和它的关键字之间建立映射关系:key--f(key)   这个关系就是散列函数/哈希函数.将一些记录存储在一块 连续 的存储空间,这块空间就是散列表/哈希表. 与线性表.树.图比较: 数据元素之间没有什么逻辑关系,也不能用连线图表示出来. 问题: 关键字不同,但通过散列函数计算的结果相同,即出现了冲突 collisi

非对称算法,散列(Hash)以及证书的那些事

转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/35389657 作者:小马 这几个概念在金融电子支付领域用得比较多,我忽然觉得把它们串起来一起讲,层层引入,可能更好理解一些.希望能以最简单朴实的方式讲明白他们之间的关系. 一非对称算法 关于非对称算法,你只要知道下面这些就行了,密钥是一对,一个叫公钥,一个叫私钥,前者公开,后者保密.假设你有一对公私钥,给你一串数据,你可以用私钥加密,然后把密文和公钥都放出去,别人可以用这个公钥解

MD5(单向散列算法)原理分析

注:本文章转载于网络. MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能:    输入任意长度的信息,经过处理,输出为128位的信息(数字指纹):    不同的输入得到的不同的结果(唯一性):    根据128位的输出结果不可能反推出输入的信息(不可逆): MD5属不属于加密算法:    认为不属于的人是因为他们觉得不能从密文(散列值)反过来得到原文,即没有

加密散列算法——MD5

引用wiki的定义,散列函数(或散列算法,英语:Hash Function)是一种从任何一种数据中创建小的数字"指纹"的方法.该函数将数据打乱混合,重新创建一个叫做散列值的指纹.散列值通常用来代表一个短的随机字母和数字组成的字符串.好的散列函数在输入域中很少出现散列冲突.在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到.(具体专业术语请自行度娘) MD5是单向散列算法的一种,全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD

散列函数之单散列算法解决冲突问题

1. 问题 问题同<简单散列函数算法> 设有10个非负整数,用不多于20个的储存单元来存放,如何存放这10个数,使得搜索其中的某一个数时,在储存单元中查找的次数最少? 问题类似于,有10个带号码的球,放到编号为{0, 1, 2, -, 19}共20个盒子中,每个盒子最多放一个,问如何放,使能够用最少的次数打开盒子,知道任一个球所在的盒子编号? 2. 分析 <简单散列函数算法>中,已经分析得出,只要能解决冲突问题,就能将查找时间降为常量范围内. 思路:当一个数发生冲突时,再找一个没有

Java哈希散列算法简介 - MD5 &amp; SHA-512

Java哈希散列算法简介 - MD5 & SHA-512 在日常的开发工作中,我们常常会碰到这样的一个场景:我们需要有一种可靠的行之有效的方法来检验跟判断数据在传输过程当中的完整性.最常见的一种情况就是当我们传输文件的时候,由于网络故障或者其他的一些因素,可能会出现我们下载下来的文件不完整,这给我们日常的开发和维护带了一些难题:另外的一个较为常用的场景就是:有没有一种行之有效的方法让我们可以很方便的判断服务器上的文件是不是有最新的数据更新,比如我们现在的移动Hybird App开发,我们经常会发

Android数据加密之SHA安全散列算法

前言: 对于SHA安全散列算法,以前没怎么使用过,仅仅是停留在听说过的阶段,今天在看图片缓存框架Glide源码时发现其缓存的Key采用的不是MD5加密算法,而是SHA-256加密算法,这才勾起了我的好奇心,所以趁着晚上没啥事,来学习一下. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes加密 Android数据加密之Des加密 Android数据加密之MD5加密 Android数据加密之Base64编码算法 SHA加密算法 SHA(Secure Hash A

数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)

数字签名是什么? 1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥. 2. 鲍勃把公钥送给他的朋友们----帕蒂.道格.苏珊----每人一把. 3. 苏珊给鲍勃写信,写完后用鲍勃的公钥加密,达到保密的效果. 4. 鲍勃收信后,用私钥解密,看到信件内容. 5. 鲍勃给苏珊回信,写完后用Hash函数,生成信件的摘要(digest). 6. 然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature). 7. 鲍勃将这个签名,附在信件下面,一起发给苏珊. 8. 苏珊收信后,取下数