《数据结构与算法JavaScript描述》散列(学习笔记C08)

相关概念

1.散列是一种常用的数据存储技术,散列后的数据可以快速地插入或取用。
2.散列使用的数据结构叫做散列表。
3.在散列表上插入、删除和取用数据都非常快,但是对于查找操作来说却效率低下。
4.我们的散列表是基于数组进行设计的。
5.使用散列表存储数据时,通过一个散列函数将键映射为一个数字,这个数字的范围是 0 到散列表的长度。

代码

// 散列

// 数组的长度需要是质数

// HashTable类(表示散列表)
function HashTable() {
    this.table = new Array(137)
//     this.simpleHash = simpleHash
    this.betterHash = betterHash
    this.showDistro = showDistro
    this.put = put
//     this.get = get
}

// 最简单的散列函数:除留余数法

// 键值为字符串时:每个字符的ASCII码值相加除以数组长度的余数
function simpleHash(data) {
    var total = 0
    for (var i=0; i<data.length; i++) {
        total += data.charCodeAt(i)
    }
    console.log('Hash value: ' + data + ' ->' + total)
    return total % this.table.length
}

// put() 将数据存入散列表
function put(data) {
    // this.simpleHash()返回键值为字符串时用除留余数法返回的键值
//     var pos = this.simpleHash(data)
    var pos = this.betterHash(data)
    this.table[pos] = data
}

// showDistro() 显示散列表中的数据
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()
// Clayton ->730 Raymond ->730 
// 这两个人名散列值一样,产生碰撞

// 改善散列函数来避免碰撞

// 避免碰撞:
// 确保散列表中用来存储数据的数组大小是给质数
// 比 100 大且不会让例 8-1 中的数据产生碰撞的第一个质数是 137
// 计算散列值的更好方法:霍纳算法
// 在此算法中,新的散列函数仍然先计算字符串中各字符的 ASCII 码值,不过求和时每次要乘以一个质数。

// 有时间可以想一下霍纳算法为什么这么做

function betterHash(string, arr) {
    const H = 37
    var total = 0
    for (var i = 0; i < string.length; ++i) {
        total += H*total + string.charCodeAt(i)
    }
    total = total % this.table.length
    if (total < 0) {
        total += this.total.length - 1
    }
    return parseInt(total)
}

// 测试
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()

// 散列化整型键

function getRandomInt(min, max) {
    return Math.floor(Math.random()*(max - min + 1))+min
}

function genStuData(arr) {
    for (var i = 0; i < arr.length; ++i) {
        var num = ''
        for (var j = 1; j <= 9; ++j) {
            num += Math.floor(Math.random()*10)
        }
        num += getRandomInt(50, 100)
        arr[i] = num
    }
}

var numStudents = 10;
var arrSize = 97;
var idLen = 9;
var students = new Array(numStudents);
genStuData(students);
console.log("Student data: \n");
for (var i = 0; i < students.length; ++i) {
    console.log(students[i].substring(0,8) + " " +
    students[i].substring(9));
}
console.log("\n\nData distribution: \n");
var hTable = new HashTable();
for (var i = 0; i < students.length; ++i) {
    hTable.put(students[i]);
}
hTable.showDistro();

// P94

未完待续P94

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值