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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM