• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    JavaScript數據結構與算法之集合與字典的介紹

    來源:懂視網 責編:小采 時間:2020-11-27 19:27:43
    文檔

    JavaScript數據結構與算法之集合與字典的介紹

    JavaScript數據結構與算法之集合與字典的介紹:本篇文章給大家帶來的內容是關于JavaScript數據結構與算法之集合與字典的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。說明:JS數據結構與算法 系列文章的代碼和示例均可在此找到一、集合Set1.1 集合數據結構集合set是一種包含不
    推薦度:
    導讀JavaScript數據結構與算法之集合與字典的介紹:本篇文章給大家帶來的內容是關于JavaScript數據結構與算法之集合與字典的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。說明:JS數據結構與算法 系列文章的代碼和示例均可在此找到一、集合Set1.1 集合數據結構集合set是一種包含不

    提供了一下幾個方法:

    add(value) 添加某個值,返回Set結構本身

    delete(value) 刪除某個值,返回一個布爾值,表示刪除是否成功

    has(value) 返回一個布爾值,表示該值是否為Set的成員

    clear() 清除所有成員,沒有返回值

    size 屬性,返回成員總數

    創建:

    直接通過數組創建:new Set([1,2,3,4])

    先實例再添加:const set = new Set(); set.add(1);

    遍歷:

    keys() 返回鍵名的遍歷器

    values() 返回鍵值的遍歷器

    entries() 返回鍵值對的遍歷器

    forEach()/for-of 使用回調函數遍歷每個成員

    二、字典Dictionary

    2.1 字典數據結構

    集合表示一組互不相同的元素(不重復的元素)。在字典中,存儲的是鍵-值對,其中鍵名是用來查詢特定元素的。字典和集合很相似,集合以值-值對的形式存儲元素,字典則是以鍵-值對的形式來存儲元素。字典也稱作映射

    類比:電話號碼簿里的名字和電話號碼。要找一個電話時,先找名字,名字找到了,緊挨著他的電話號碼也就想找到了,這里的鍵是指你用來查找的東西,值時查找得到的結果

    2.2 字典的實現

    一般字典包括下面幾種方法:

    set(key,value) 向字典中添加新元素

    remove(key) 通過使用鍵值來從字典中移除鍵值對應的數據值

    has(key) 如果某個鍵值存在于這個字典中,則返回true,反之則返回false

    get(key) 通過鍵值查找特定的數值并返回

    clear() 將這個字典中的所有元素全部刪除

    size() 返回字典所包含元素的數量。與數組的length屬性類似

    keys() 將字典所包含的所有鍵名以數組形式返回

    values() 將字典所包含的所有數值以數組形式返回

    下面將基于對象實現基礎的字典

    class Dictionary {
     constructor() {
     this._table = {};
     this._length = 0;
     }
    
     set(key, value) {
     if (!this.has(key)) {
     this._length += 1;
     }
     this._table[key] = value;
     }
    
     has(key) {
     return this._table.hasOwnProperty(key);
     }
    
     remove(key) {
     if (this.has(key)) {
     delete this._table[key];
     this._length -= 1;
     return true;
     }
     return false;
     }
    
     get(key) {
     return this._table[key];
     }
    
     clear() {
     this._table = {};
     this._length = 0;
     }
    
     size() {
     return this._length;
     }
    
     keys() {
     return Object.keys(this._table);
     }
    
     values() {
     return Object.values(this._table);
     }
    }

    這里添加成員時,并未考慮key為對象的情況,以至于會出現如下情況:

    const obj = {};
    obj[{a: 1}] = 1;
    obj[{a: 2}] = 2;
    
    console.log(obj[{a: 1}]); // 2
    
    // 對象形式的鍵會以其toSting方法的結果存儲
    obj; // {[object Object]: 2}

    在ES6中支持key值為對象形式的字典數據結構Map,其提供的方法如下:

    提供了一下幾個方法:

    set(key, value) set方法設置鍵名key對應的鍵值為value,然后返回整個Map結構

    get(key) get方法讀取key對應的鍵值,如果找不到key,返回undefined

    delete(value) 刪除某個值,返回一個布爾值,表示刪除是否成功

    has(value) 返回一個布爾值,表示該值是否為Map的成員

    clear() 清除所有成員,沒有返回值

    size 屬性,返回成員總數

    創建:

    直接通過數組創建:const map = new Map([ ['name', '張三'], ['title', 'Author'] ]);

    先實例再添加:const map = new Map();

    遍歷:

    keys() 返回鍵名的遍歷器

    values() 返回鍵值的遍歷器

    entries() 返回鍵值對的遍歷器

    forEach()/for-of 使用回調函數遍歷每個成員

    三、哈希表/散列表

    3.1 哈希表數據結構

    散列表也叫哈希表(HashTable也叫HashMap),是Dictionary類的一種散列表實現方式

    (1)哈希表有何特殊之處:

    數組的特點是尋址方便,插入和刪除困難;而鏈表的特點是尋址困難,插入和刪除方便。哈希表正是綜合了兩者的優點,實現了尋址方便,插入刪除元素也方便的數據結構

    (2)哈希表實現原理

    哈希表就是把Key通過一個固定的算法函數既所謂的哈希函數轉換成一個整型數字,然后將該數字對數組長度進行取余,取余結果就當作數組的下標,將value存儲在以該數字為下標的數組空間里。而當使用哈希表進行查詢的時候,就是再次使用哈希函數將key轉換為對應的數組下標,并定位到該空間獲取value,如此一來,就可以充分利用到數組的定位性能進行數據定位

    下面是將key中每個字母的ASCII值之和作為數組的索引(哈希函數)的圖例:

    2025119721-5c4ec991ca61b_articlex.png

    (3)數組的長度為什么選擇質數

    書中有如下說明:

    散列函數的選擇依賴于鍵值的數據類型。如果鍵是整數,最簡單的散列函數就是以數組的長度對鍵取余。在一些情況下,比如數組的長度為10,而鍵值都是10的倍數時,就不推薦使用這種方式了。這也是數組的長度為什么要是質數的原因之一。如果鍵是隨機的整數,而散列函數應該更均勻地分布這些鍵,這種散列方式稱為除留余數法

    3.2 哈希表的實現

    我們為哈希表實現下面幾個方法:

    hashMethod 哈希函數,將字符串轉換成索引

    put 添加鍵值

    get 由鍵獲取值

    remove 移除鍵

    class HashTable {
     constructor() {
     this._table = [];
     }
    
     // 哈希函數【社區中實踐較好的簡單哈希函數】
     hashMethod(key) {
     if (typeof key === 'number') return key;
    
     let hash = 5381;
     for (let i = 0; i < key.length; i += 1) {
     hash = hash * 33 + key.charCodeAt(i);
     }
     return hash % 1013;
     }
    
     put(key, value) {
     const pos = this.hashMethod(key);
     this._table[pos] = value;
     }
    
     get(key) {
     const pos = this.hashMethod(key);
     return this._table[pos];
     }
    
     remove(key) {
     const pos = this.hashMethod(key);
     delete this._table[pos];
     }
    
     print() {
     this._table.forEach((item, index) => {
     if (item !== undefined) {
     console.log(index + ' --> ' + item);
     }
     })
     }
    }

    當然了,一個簡單的哈希函數,將不同的字符串轉換成整數時,很有可能會出現多個不同字符串轉換后對應同一個整數,這個就需要進行沖突的處理

    3.3 處理沖突的方法

    (1)分離鏈接

    分離鏈接法包括為散列表的每一個位置創建一個鏈表并將元素存儲在里面。它是解決沖突的
    最簡單的方法,但是它在HashTable實例之外還需要額外的存儲空間

    2126829608-5c4ec9a0cd51f_articlex.png

    (2)線性探查

    當想向表中某個位置加入一個新元素的時候,如果索引 為index的位置已經被占據了,就嘗試index+1的位置。如果index+1的位置也被占據了,就嘗試 index+2的位置,以此類推

    1556827884-5c4ec9ac3d790_articlex.png

    四、bitMap算法

    4.1 bitMap數據結構

    bitMap數據結構常用于大量整型數據做去重和查詢,《Bitmap算法》這篇文章中是基于Java語言及數據庫優化進行解釋的圖文教程

    bitMap是利用了二進制來描述狀態的一種數據結構,下面介紹其簡單的原理:

    (1)思考下面的問題

    街邊有8棧路燈,編號分別是1 2 3 4 5 6 7 8 ,其中2號,5號,7號,8號路燈是亮著的,其余的都處于不亮的狀態,請你設計一種簡單的方法來表示這8棧路燈亮與不亮的狀態。

    路燈 1 2 3 4 5 6 7 8
    狀態 0 1 0 0 1 0 1 1

    將狀態轉化為二進制parseInt(1001011, 2);結果為75。一個Number類型的值為32個字節,它可以表示32棧路燈的狀態。這樣在大數據量的處理中,bitMap就有很大的優勢。

    (2)位運算介紹

    1、按位與&: 3&7=3【011 & 111 --> 011】

    2、按位或|: 3|7=7【011 | 111 --> 111】

    3、左位移<<: 1<<3=8【1 --> 1000】

    (3)實踐

    一組數,內容以為 3,6,7,9,請用一個整數來表示這些四個數

    var value = 0;
    value = value | 1<<3; // 1000
    value = value | 1<<6; // 1001000
    value = value | 1<<7; // 11001000
    value = value | 1<<9; // 1011001000
    console.log(value); // 712

    這樣,十進制數712的二進制形式對應的位數為1的值便為數組中的樹值

    4.2 bitMap的實現

    通過上面的介紹,我們可以實現一個簡單的bitMap類,有下面兩個方法:

    addMember添加成員

    isExist成員是否存在

    分析:

    1、單個數值既能表示0~32的值,若以數組作為基礎,bitMap能容納的成員由數組長度決定64*數組長度

    2、addMember添加成員:數組/位數向下取整表示所在索引,數組/位數取余表示所在二進制的位數

    3、isExist成員是否存在:添加成員的反向計算

    我們先實現基礎讀寫位的方法

    export const BIT_SIZE = 32;
    
    // 設置位的值
    export function setBit(bitMap, bit) {
     const arrIndex = Math.floor(bit / BIT_SIZE);
     const bitIndex = Math.floor(bit % BIT_SIZE);
     bitMap[arrIndex] |= (1 << bitIndex);
    }
    
    // 讀取位的值
    export function getBit(bitMap, bit) {
     const arrIndex = Math.floor(bit / BIT_SIZE);
     const bitIndex = Math.floor(bit % BIT_SIZE);
     return bitMap[arrIndex] & (1 << bitIndex);
    }

    進而根據上面的方法得到下面的類

    class BitMap {
     constructor(size) {
     this._bitArr = Array.from({
     length: size
     }, () => 0);
     }
    
     addMember(member) {
     setBit(this._bitArr, member);
     }
    
     isExist(member) {
     const isExist = getBit(this._bitArr, member);
     return Boolean(isExist);
     }
    }
    
    // 驗證
    const bitMap = new BitMap(4);
    const arr = [0, 3, 5, 6, 9, 34, 23, 78, 99];
    for(var i = 0;i < arr.length;i++){
     bitMap.addMember(arr[i]);
    }
    
    console.log(bitMap.isExist(3)); // true
    console.log(bitMap.isExist(7)); // false
    console.log(bitMap.isExist(78)); // true

    注意:這種結構也有其局限性

    1、數據集要求較為緊湊,[1, 1000000]這種結構空間利用過低,不利于發揮bitMap的優勢

    2、僅對整數有效(當然,我們可以通過哈希函數將字符串轉換為整型)

    4.3 bitMap的應用

    (1)大數據排序

    要求:有多達10億無序整數,已知最大值為15億,請對這個10億個數進行排序
    分析:大數據的排序,傳統的排序方式相對內存占用較大,使用bitMap僅占原內存的(JS中為1/64,Java中為1/32)

    實現:模擬大數據實現,如下(最大值為99)

    const arr = [0, 6, 88, 7, 73, 34, 10, 99, 22];
    const MAX_NUMBER = 99;
    
    const ret = [];
    const bitMap = new BitMap(4);
    arr.forEach(item => { bitMap.addMember(item); })
    
    for (let i = 0; i <= MAX_NUMBER; i += 1) {
     if (bitMap.isExist(i)) ret.push(i);
    }
    
    console.log(ret); // [ 0, 6, 7, 10, 22, 34, 73, 88, 99 ]

    (2)兩個集合取交集

    要求:兩個數組,內容分別為[1, 4, 6, 8, 9, 10, 15], [6, 14, 9, 2, 0, 7],請用BitMap計算他們的交集
    分析:利用isExist()來篩選相同項

    實現:

    const arr1 = [1, 4, 6, 8, 9, 10, 15];
    const arr2 = [6, 14, 9, 2, 0, 7];
    const intersectionArr = []
    
    const bitMap = new BitMap();
    arr1.forEach(item => bitMap.addMember(item))
    
    arr2.forEach(item => {
     if (bitMap.isExist(item)) {
     intersectionArr.push(item);
     }
    })
    
    console.log(intersectionArr); // [6, 9]

    BitMap數據結構的用法原不止如此,我們可以通過哈希函數將字符串轉換成整數,再進行處理。當然,我們應該始終牢記BitMap必須是相對較為緊密的數字,否則無法發揮BitMap的最大功效

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    JavaScript數據結構與算法之集合與字典的介紹

    JavaScript數據結構與算法之集合與字典的介紹:本篇文章給大家帶來的內容是關于JavaScript數據結構與算法之集合與字典的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。說明:JS數據結構與算法 系列文章的代碼和示例均可在此找到一、集合Set1.1 集合數據結構集合set是一種包含不
    推薦度:
    標簽: 介紹 js 集合
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产精品国产三级国产AV主播| 国产精品污视频| 亚洲精品宾馆在线精品酒店| 国产精品无码专区| 午夜国产精品无套| 国产精品午夜一级毛片密呀| 国产精品大白天新婚身材| 人人妻人人澡人人爽精品日本 | 亚洲AV无码成人精品区狼人影院 | 91麻豆精品国产| 久久亚洲精品国产精品| 欧美成人精品高清视频在线观看| 亚洲成人精品久久| 狠狠色丁香婷婷综合精品视频| 国内精品久久久久伊人av| 午夜欧美精品久久久久久久| 亚洲精品国产综合久久一线| 免费精品久久久久久中文字幕 | 尤物国精品午夜福利视频| 91精品成人免费国产| 日韩av无码久久精品免费| 亚洲国产精品成人| 国产一区二区精品久久岳| 国产精品成人99久久久久| 色偷偷888欧美精品久久久| 国产精品久久久久影视不卡| 国产精品高清一区二区人妖| 久久91精品久久91综合| 久久久久免费精品国产| 国产午夜精品一区理论片| 国产精品怡红院永久免费| 久久99精品国产99久久| 久久99国产精品久久99| 久久99精品国产麻豆宅宅| 午夜精品视频在线观看| 成人国产精品一区二区视频| 国产精品JIZZ在线观看老狼| 国产精品区AV一区二区| 久久人人爽人人精品视频| 亚洲av无码国产精品色在线看不卡 | 精品无码久久久久久尤物|