Map底层实现

Map和普通的设置对象的区别

普通的对象设置 设置key 为 1 和 '1' 都是一样的 会发生隐式类型转换

Map不会发生
---------------------------------------------------------------------
Map底层的实现

Map数据结构查找速度之所以快 是因为它的底层实现并不是我们所能想到的数据遍历

而是用到了邻接链表+桶排序+红黑树
---------------------------------------------------------------------
首先我们为什么要到邻接链表?

其实我们可以通过数组方法实现 但是数组不好的点在于它的查找速度特别的慢也
不能说特别慢 如果我们一个数组的长度很长 恰巧我们需要查找的元素在最后一位
我们需要遍历很多次 如果我们用到了邻接链表 邻接链表里面包括了一种新的排序方法
桶排序,什么意思呢?就是我们可以将一类的数放到一起,当链表单个长度超过阈值(8)时
将链表转换为红黑树,这样大大减少了查找时间。如果所有桶都装满了就将桶的数量添加
为原来的1/2,然后将数值重新排序,阈值的规定为了确保查找的速度最快。
---------------------------------------------------------------------

1.hash算法(散列算法)
它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法
2.桶排序的思想
桶排序目的是以扩大内存空间为代价,从而减少时间复杂度,可以将同一种类型的
数据放到一起 方便查找。

为了确保查找的速度 Map底层通过两种方式 首先当后面结构的长度大于规定的阈值 将桶
的数量添加原来的一倍 然后重新进行排序 第二种当后面值的长度很大可以通过红黑树将
结构分为2部分 就好比 二叉树 减少查找速度。

对于对象叫做完全hash 每个对象都对应一个桶。
--------------------------------------------------------------------------
//Map底层的实现原理 桶的思想
function Map () {
this.start()
}

Map.prototype.len = 8; // 定义桶的长度
Map.prototype.bucket = []; //定义一个桶
Map.prototype.start = function () { //初始化桶
for(let i = 0; i < this.len; i++){
this.bucket[i] = {next : null} //让桶的每一位都为 空
}
}
//处理hash值
Map.prototype.makeHash = function (key) {
let hash = 0; //定义初始hash值
if((typeof key) == 'string'){ //判断传进来的是不是字符串
let len = (key.length > 3) ? key.length : 3; //判断key的长度
for(var i = len - 3; i < len; i++){ //循环每一项
//判断每一位是否等于undefined 如(false,null)如果等于就为0 不是就返回他的charCode编码(最多只返回三位)
hash += (key[i] !== undefined) ? key[i].charCodeAt() : 0;
}
}else{
hash = +key //不是字符串 如 false true 返回+key的值
}
return hash; //返回hash
}
Map.prototype.set = function (key,value) {
let hash = this.makeHash(key); //拿到key所对应的hash值
let list = this.bucket[hash % this.len] //确定在桶里面的位置
let nextNode = list; // 给下一个赋值
while(nextNode.next){ //判断下面一位还有没有next
if(nextNode.key === key){ //如果nextNode的key 等于 传进来的 key 让value也相等
nextNode.value = value;
return
}else{
nextNode = nextNode.next; // 如果不等于 给nextNode重新赋值为nextNode的下一位
}
}
//如果没有next 重新定义一个next
nextNode.next = {key,value,next : null}
}

Map.prototype.get = function (key) {
let hash = this.makeHash(key); //拿到key所对应的hash值
let list = this.bucket[hash % this.len]; //确定在桶里面的位置
let nextNode = list; // 给下一个赋值
while(nextNode){ //判断当前位置nextNode有没有值
if(nextNode.key === key){ //如果nextNode的key 等于 传进来的 key 直接return对应的值
return nextNode.value;
}else{
nextNode = nextNode.next; // 如果不等于 给nextNode重新赋值为nextNode的下一位
}
}
return undefined;
}

Map.prototype.has = function (key) {
let hash = this.makeHash(key) //拿到key所对应的hash值
let list = this.bucket[hash % this.len] //确定在桶里面的位置
let nextNode = list; // 给下一个赋值
while(nextNode){ //判断当前位置nextNode有没有值
if(nextNode.key === key){ //如果nextNode的key 等于 传进来的 key 直接返回true
return true
}else{
nextNode = nextNode.next; // 如果不等于 给nextNode重新赋值为nextNode的下一位
}
}
//如果没有next 返回false
return false;
}

Map.prototype.delete = function (key) {
let hash = this.makeHash(key) //拿到key所对应的hash值
let list = this.bucket[hash % this.len] //确定在桶里面的位置
let nextNode = list; // 给下一个赋值
while(nextNode.next){ //判断下面一位还有没有next
if(nextNode.next.key === key){ //如果nextNode的key 等于 传进来的 key 直接返回true
nextNode.next = nextNode.next.next //如果删除的是next的位置 让删除的哪一位的next变成原来的位置上
return true //提示删除成功
}else{
nextNode = nextNode.next; // 如果不等于 给nextNode重新赋值为nextNode的下一位
}
}
//如果没有next 返回false
return false;
}
Map.prototype.clear = function () {
this.start() //让桶初始化
}
let map = new Map()

转载于:https://www.cnblogs.com/2030xx/p/9843710.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unordered_map底层实现一般是基于哈希表(Hash Table)。哈希表是一种使用哈希函数将键映射到存储位置的数据结构。 在C++中,unordered_map是标准库中的一个关联容器,它提供了键值对的映射。它的底层实现使用了哈希表来实现快速查找和插入。 具体地说,unordered_map使用一个数组来存储元素,这个数组被称为桶(buckets)。每个桶中存放了一个链表或者红黑树,用来解决哈希冲突(不同的键对应相同的哈希值)的问题。 当插入一个键值对时,unordered_map首先会计算出键的哈希值,然后通过哈希函数将哈希值映射为桶的索引。如果该桶为空,就直接将键值对插入到这个桶中;如果桶中已经存在其他键值对,就使用键进行比较来判断是否已经存在相同的键,如果有相同的键,则更新对应的值;如果没有相同的键,则将新的键值对插入到链表或者红黑树中。 在查找一个键值对时,unordered_map首先计算出键的哈希值,并通过哈希函数找到对应的桶。然后在桶中进行搜索,如果是链表,则按顺序比较键值对的键;如果是红黑树,则使用树的搜索算法来查找。 哈希表的优点是可以在平均情况下实现常数时间的插入、删除和查找操作。然而,它的缺点是对内存的利用率相对较低,并且在最坏情况下,时间复杂度可能退化为O(n),其中n是存储的键值对的数量。 这就是unordered_map底层实现的简要介绍,它使用哈希表来实现快速查找和插入,并且处理了哈希冲突的情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值