数据结构:JavaScript实现散列

本文介绍了散列作为一种高效的数据存储技术,特别是在JavaScript中如何实现。文章详细讲解了散列表的设计,数组长度的选择通常为质数。接着,讨论了一个不完整的散列示例,指出相同键导致的碰撞问题,并提出线性探测法作为解决碰撞的一种策略,当数组大小足够时,这种方法能有效利用空闲单元格存储数据。
摘要由CSDN通过智能技术生成

一.引言

散列是一种常用的数据存储技术,散列后的数据可以快速的插入或者取用,散列使用的数据结构叫做散列表。

我们的散列是基于数组进行设计的,数组的长度是事先设定的,如有需要可以随时增加,,所有元素根据该元素对应的键,保存在数组的特定位置,该键和字典中的键是类似的概念,使用散列表来存储数据时,通过一个散列函数将键映射为一个数字,这个数字的范围是0到散列表的长度。

需要注意的是:散列表中的数组应该设为多大? 这个问题是编写散列函数时必须要思考的,对数组大小常见的限制就是:数组长度应该是一个质数。

二.一个不完整的散列

首先我们来看一段代码

//使用一个类来表示散列表
function HashTable(data){
	this.table = new Array(137);
	//散列表中数据分布的方法
	this.simpleHash = simpleHash;
	//从散列表中读取数据的方法
	this.showDistro = showDistro;
	//向散列表中插入数据的方法
	this.put = put;
}
function simpleHash(data){
	var total = 0;
	//将字符串中每个字符的ascII码值相加
	for(var i = 0; i < data.length; ++i){
		total += data.charCodeAt(i);
	}
	//将ascII值的和除以数组长度的余数作为散列值
	return total % this.table.length;
}
function put(data){
	var pos = this.simpleHash(data);
	this.table[pos] = data;
}
function showDistro(){
	var n = 0;
	for(var i = 0; i < this.table.length; ++i){
		if(this.table[i] != undefined){
			console.log(i + ":" + this.table[i]);
		}
	}
}

var someNames = ["David", "Jennifer", "Donnie", "Raymond", "Cynthia", "Mike", "Clayton", "Danny", "Jonathan"];
var hTable = new HashTable();
for(var i = 0; i < someNames.length; ++i){
	hTable.put(someNames[i]);
}
hTable.showDistro();


仔细观察,我们可以发现someNames中的元素并没有全部显示,Raymond不见了

这是因为字符串Clayton和Raymond的散列值是一样的,都是45,一样的散列值引发了碰撞!

下面我们来考虑一下处理碰撞的方法

三.如何处理

1.线性探测法

当发生碰撞时,线性探测法检查散列中的下一个位置是否为空,如果为空,则将数据存入在该位置,如果不为空,则继续寻找下一个位置,直到找到一个空的位置为止。

该技术是基于这样一个事实:每个散列都会有很多空的单元格,可以使用他们来存储数据。

注意:如果数组的大小是带存储数据的两倍以及两倍以上时,我们采用线性探测法。

修改put函数,代码如下

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

运行结果















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值