国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Javascript的數(shù)據(jù)結(jié)構(gòu)與算法(二)

jlanglang / 2530人閱讀

摘要:基本版的散列表實(shí)現(xiàn)在散列表中我們通過(guò)散列函數(shù)來(lái)確定鍵值對(duì)的關(guān)系。的實(shí)現(xiàn)具體看的數(shù)據(jù)結(jié)構(gòu)與算法一。散列函數(shù)不超過(guò)數(shù)組的長(zhǎng)度下面兩個(gè)值相同源碼地址的數(shù)據(jù)結(jié)構(gòu)與算法二源碼

1集合 1.1集合的實(shí)現(xiàn)

集合是由一組無(wú)序且唯一(即不能重復(fù))的項(xiàng)組成的。這個(gè)數(shù)據(jù)結(jié)構(gòu)使用了與有限集合相同 的數(shù)學(xué)概念,但應(yīng)用在計(jì)算機(jī)科學(xué)的數(shù)據(jù)結(jié)構(gòu)中。

集合中常用方法列表:

add(value):向集合中添加一個(gè)新的項(xiàng)。

remove(value):從集合中移除一個(gè)值。

has(value):如果在集合中,返回true,否則返回false。

clear():清除集合中的所有項(xiàng)。

size():返回集合所包含元素的數(shù)量。

values():返回一個(gè)包含集合中所有值得數(shù)組。

union(otherSet):并集操作,返回一個(gè)包含兩個(gè)集合中所有元素的新集合。

intersection(otherSet):交集操作,返回一個(gè)包含兩個(gè)集合中共有元素的新集合。

difference(otherSet):差集操作,返回一個(gè)包含左右存在于第一個(gè)集合并且不存在于第二個(gè)集合的元素的新集合。

subset(otherSet):子集操作,驗(yàn)證一個(gè)給定集合是否是另一個(gè)集合的子集,返回true和false。

    function Set() {
        this.items = {};
    }
    Set.prototype = {
        constructor: Set,
        has: function(value) {
            return value in this.items;
        },
        add: function(value) {
            if (!this.has(value)) {
                this.items[value] = value;
                return true;
            }
            return false;
        },
        remove: function(value) {
            if (this.has(value)) {
                delete this.items[value];
                return true;
            }
            return false;
        },
        clear: function() {
            this.items = {};
        },
        size: function() {
            return Object.keys(this.items).length;
        },
        values: function() {
            return Object.keys(this.items);
        },
        union: function(otherSet) {
            var unionSet = new Set();
            var values = this.values();
            for (var i = 0; i < values.length; i++) {
                unionSet.add(values[i]);
            }
            values = otherSet.values();
            for (var i = 0; i < values.length; i++) {
                unionSet.add(values[i]);
            }
            return unionSet;
        },
        intersection: function(otherSet) {
            var intersectionSet = new Set();
            var values = this.values();
            for (var i = 0; i < values.length; i++) {
                if (otherSet.has(values[i])) {
                    intersectionSet.add(values[i]);
                }
            }
            return intersectionSet;
        },
        difference: function(otherSet) {
            var differenceSet = new Set();
            var values = this.values();
            for (var i = 0; i < values.length; i++) {
                if (!otherSet.has(values[i])) {
                    differenceSet.add(values[i]);
                }
            }
            return differenceSet;
        },
        subset: function(otherSet) {
            if (this.size() > otherSet.size()) {
                return false;
            } else {
                var values = this.values();
                for (var i = 0; i < values.length; i++) {
                    if (!otherSet.has(values[i])) {
                        return false;
                    }
                }
            }
            return true;
        },
    };
1.2集合的使用
    var set = new Set();
    set.add(1);
    console.log(set.values());//["1"]
    console.log(set.has(1));//true
    console.log(set.size());//1
    set.add(2);
    console.log(set.values());//["1","2"]
    console.log(set.has(2));//true
    console.log(set.size());//2
    set.remove(2);
    console.log(set.values());//["1"]

交集、并集、子集、差集的使用。

    //并集測(cè)試
    var setA = new Set();
    setA.add(1);
    setA.add(2);
    setA.add(3);
    var setB = new Set();
    setB.add(3);
    setB.add(4);
    setB.add(5);
    setB.add(6);
    var setAB = setA.union(setB);
    console.log(setAB.values()); // ["1", "2", "3", "4", "5", "6"]
    //交集測(cè)試
    setA = new Set();
    setA.add(1);
    setA.add(2);
    setA.add(3);
    setB = new Set();
    setB.add(2);
    setB.add(3);
    setB.add(4);
    var intersectionAB = setA.intersection(setB);
    console.log(intersectionAB.values()); // ["2", "3"]
    //差集側(cè)事故
    setA = new Set();
    setA.add(1);
    setA.add(2);
    setA.add(3);
    setB = new Set();
    setB.add(2);
    setB.add(3);
    setB.add(4);
    var differenceAB = setA.difference(setB);
    console.log(differenceAB.values()); //["1"]
    //子集測(cè)試
    setA = new Set();
    setA.add(1);
    setA.add(2);
    var setB = new Set();
    setB.add(1);
    setB.add(2);
    setB.add(3);
    setC = new Set();
    setC.add(2);
    setC.add(3);
    setC.add(4);
    console.log(setA.subset(setB)); //true
    console.log(setA.subset(setC)); //false
2字典和散列表

集合、字典和散列表可以存儲(chǔ)不重復(fù)的值。在集合中,我們感興趣的是每個(gè)值本身,并把它 當(dāng)作主要元素。在字典中,我們用[鍵,值]的形式來(lái)存儲(chǔ)數(shù)據(jù)。在散列表中也是一樣(也是以[鍵, 值]對(duì)的形式來(lái)存儲(chǔ)數(shù)據(jù))。

2.1字典

集合表示一組互不相同的元素(不重復(fù)的元素)。在字典中,存儲(chǔ)的是[鍵,值] 對(duì),其中鍵名是用來(lái)查詢特定元素的。字典和集合很相似,集合以[值,值]的形式存儲(chǔ)元素,字 典則是以[鍵,值]的形式來(lái)存儲(chǔ)元素。字典也稱(chēng)作映射。下面是字典需要實(shí)現(xiàn)的方法:

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

remove(key): 通過(guò)使用鍵值來(lái)從字典中語(yǔ)出鍵值對(duì)應(yīng)的數(shù)據(jù)值。

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

get(key): 通過(guò)鍵值查詢特定的數(shù)值并且返回。

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

size(): 返回字典中包含元素的數(shù)量。

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

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

getItems(): 返回字典。

2.1.1字典的實(shí)現(xiàn)
    function Dictionary() {
        this.items = {};
    }
    Dictionary.prototype = {
        constructor: Dictionary,
        has: function(key) {
            return key in this.items;
        },
        set: function(key, value) {
            this.items[key] = value;
        },
        remove: function(key) {
            if (this.has(key)) {
                delete this.items[key];
                return true;
            }
            return false;
        },
        get: function(key) {
            return this.has(key) ? this.items[key] : undefined;
        },
        values: function() {
            var values = [];
            for (var key in this.items) {
                if (this.has(key)) {
                    values.push(key);
                }
            }
            return values;
        },
        clear: function() {
            this.items = {};
        },
        size: function() {
            return Object.keys(this.items).length;
        },
        keys: function() {
            return Object.keys(this.items);
        },
        getItems: function() {
            return this.items;
        }
    };
2.1.2字典的基本使用
    var dictionary = new Dictionary();
    console.log(dictionary.size()); //0
    dictionary.set("first", "huang");
    dictionary.set("second", "cheng");
    dictionary.set("third", "du");
    console.log(dictionary.has("first")); //true
    console.log(dictionary.get("second")); //cheng
    console.log(dictionary.values()); // ["first", "second", "third"]
    dictionary.remove("second");
    console.log(dictionary.keys()); //["first", "third"]
    console.log(dictionary.getItems()); //{ first="huang",  third="du"}
2.2散列表

HashTable類(lèi),也叫HashMap類(lèi),是Dictionary類(lèi)的一種散列表實(shí)現(xiàn)方式。散列算法的作用是盡可能快地在數(shù)據(jù)結(jié)構(gòu)中找到一個(gè)值。在之前的章節(jié)中,你已經(jīng)知道如果 要在數(shù)據(jù)結(jié)構(gòu)中獲得一個(gè)值(使用get方法),需要遍歷整個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)找到它。如果使用散列 函數(shù),就知道值的具體位置,因此能夠快速檢索到該值。散列函數(shù)的作用是給定一個(gè)鍵值,然后 返回值在表中的地址。

2.2.1基本版的散列表實(shí)現(xiàn)

在散列表中我們通過(guò)散列函數(shù)來(lái)確定鍵值對(duì)的關(guān)系。基本方法如下:

put(key,value): 向散列表增加一個(gè)新的選項(xiàng)(也可能是更新散列表)。

remove(key): 根據(jù)鍵值從散列表中移除值。

get(key): 返回根據(jù)鍵值檢索到的特定值。

對(duì)于HashTable類(lèi)來(lái)說(shuō),我們不需要像ArrayList類(lèi)一樣從table數(shù)組中將位置也移除。由 于元素分布于整個(gè)數(shù)組范圍內(nèi),一些位置會(huì)沒(méi)有任何元素占據(jù),并默認(rèn)為undefined值。我們也 不能將位置本身從數(shù)組中移除(這會(huì)改變其他元素的位置),否則,當(dāng)下次需要獲得或移除一個(gè) 元素的時(shí)候,這個(gè)元素會(huì)不在我們用散列函數(shù)求出的位置上。

    //lose-los散列函數(shù)
    function loseloseHashCode(key) {
        var hash = 0;
        for (var i = 0; i < key.length; i++) {
            hash += key.charCodeAt(i);
        }
        return hash % 37;
    }

    function HashTable() {
        this.table = [];
    }
    HashTable.prototype = {
        constructor: HashTable,
        put: function(key, value) {
            var position = loseloseHashCode(key);
            console.log(position + "- " + key);
            this.table[position] = value;
        },
        get: function(key) {
            return this.table[loseloseHashCode(key)];
        },
        remove: function(key) {
            this.table[loseloseHashCode(key)] = undefined;
        }
    };

    var hash = new HashTable();
    hash.put("Gandalf", "gandalf@email.com");
    hash.put("John", "johnsnow@email.com");
    hash.put("Tyrion", "tyrion@email.com");
    console.log(hash.get("Gandalf")); //gandalf@email.com
    console.log(hash.get("Loiane")); //undefined
    hash.remove("Gandalf");
    console.log(hash.get("Gandalf")); //undefined

有時(shí)候,一些鍵會(huì)有相同的散列值。不同的值在散列表中對(duì)應(yīng)相同位置的時(shí)候,我們稱(chēng)其為沖突。當(dāng)這種情況發(fā)生的時(shí)候就要去解決它。處理沖突有幾種方法:分離鏈接、線性探查和雙散列法,我們會(huì)介紹前兩種方法。對(duì)于分離鏈接和線性探查來(lái)說(shuō),只需要重寫(xiě)三個(gè)方法:put、get和remove。這三個(gè)方法在 每種技術(shù)實(shí)現(xiàn)中都是不同的。

2.2.2分離鏈接版散列表

為了實(shí)現(xiàn)一個(gè)使用了分離鏈接的HashTable實(shí)例,我們需要一個(gè)新的輔助類(lèi)來(lái)表示將要加入LinkedList實(shí)例的元素。我們管它叫ValuePair類(lèi)。LinkedList的實(shí)現(xiàn)具體看javascript的數(shù)據(jù)結(jié)構(gòu)與算法(一).html)。

分離鏈接:分離鏈接法包括為散列表的每一個(gè)位置創(chuàng)建一個(gè)鏈表并將元素存儲(chǔ)在里面。它是解決沖突的最簡(jiǎn)單的方法,但是它在HashTable實(shí)例之外還需要額外的存儲(chǔ)空間。

    function HashTable() {
        this.table = []; 
        //lose-los散列函數(shù) 
        function loseloseHashCode(key) {
            var hash = 0;
            for (var i = 0; i < key.length; i++) {
                hash += key.charCodeAt(i);
            }
            //console.log(key + " - " + (hash % 37));
            return hash % 37;
        }

        function ValuePair(key, value) {
            this.key = key;
            this.value = value;
            this.toString = function() {
                return "[" + this.key + " - " + this.value + "]";
            }
        }
        if ((typeof this.put !== "function") && (typeof this.put !== "string")) {
            HashTable.prototype.put = function(key, value) {
                var position = loseloseHashCode(key);
                if (this.table[position] === undefined) {
                    this.table[position] = new LinkedList();
                }
                this.table[position].append(new ValuePair(key, value));
            };
            HashTable.prototype.get = function(key) {
                var position = loseloseHashCode(key);
                if (this.table[position] !== undefined) {
                    var current = this.table[position].getHead();
                    while (current.next) {
                        if (current.element.key === key) {
                            return current.element.value;
                        }
                        current = current.next;
                    }
                    //第一個(gè)元素或者最后一個(gè)元素
                    if (current.element.key === key) {
                        return current.element.value;
                    }
                } else {
                    return undefined;
                }
            };
            HashTable.prototype.remove = function(key) {
                var position = loseloseHashCode(key);
                if (this.table[position] !== undefined) {
                    var current = this.table[position].getHead();
                    while (current.next) {
                        if (current.element.key === key) {
                            this.table[position].remove(current.element);
                            if (this.table[position].isEmpty()) {
                                this.table[position] = undefined;
                            }
                            return true;
                        }
                        current = current.next;
                    }
                    //檢查是否是第一個(gè)或者最后一個(gè)
                    if (current.element.key === key) {
                        this.table[position].remove(current.element);
                        if (this.table[position].isEmpty()) {
                            this.table[position] = undefined;
                        }
                        return true;
                    }
                }
                return false;
            };
        }
    }
    var hash = new HashTable();
    hash.put("Gandalf", "gandalf@email.com");
    hash.put("John", "johnsnow@email.com");
    //下面兩個(gè)hash值相同
    hash.put("Aaron", "huang@gmail.com");
    hash.put("Tyrion", "tyrion@email.com");
    console.log(hash.get("Gandalf")); //gandalf@email.com
    console.log(hash.get("Loiane")); //undefined
    hash.remove("Gandalf");
    console.log(hash.get("Gandalf")); //undefined
2.2.3線性探查版散列表

另一種解決沖突的方法是線性探查。當(dāng)想向表中某個(gè)位置加入一個(gè)新元素的時(shí)候,如果索引為index的位置已經(jīng)被占據(jù)了,就嘗試index+1的位置。如果index+1的位置也被占據(jù)了,就嘗試 index+2的位置,以此類(lèi)推。

    function HashTable() {
        this.table = []; //lose-los散列函數(shù) 
        function loseloseHashCode(key) {
            var hash = 0;
            for (var i = 0; i < key.length; i++) {
                hash += key.charCodeAt(i);
            }
            //console.log(key + " - " + (hash % 37));
            return hash % 37;
        }

        function ValuePair(key, value) {
            this.key = key;
            this.value = value;
            this.toString = function() {
                return "[" + this.key + " - " + this.value + "]";
            }
        }
        if ((typeof this.put !== "function") && (typeof this.put !== "string")) {
            HashTable.prototype.put = function(key, value) {
                var position = loseloseHashCode(key);
                if (this.table[position] === undefined) {
                    this.table[position] = new ValuePair(key, value);
                } else {
                    var index = position + 1;
                    while (this.table[index] !== undefined) {
                        index++;
                    }
                    this.table[index] = new ValuePair(key, value);
                }
            };
            HashTable.prototype.get = function(key) {
                var position = loseloseHashCode(key);
                if (this.table[position] !== undefined) {
                    if (this.table[position].key === key) {
                        return this.table[position].value;
                    } else {
                        var index = position + 1;
                        //index不超過(guò)數(shù)組的長(zhǎng)度
                        while (((this.table[index] === undefined) || (this.table[index].key !== key)) && (index < this.table.length)) {
                            index++;
                        }
                        if (this.table[index] && (this.table[index].key === key)) {
                            return this.table[index].value;
                        } else {
                            return undefined;
                        }
                    }
                } else {
                    return undefined;
                }
            };
            HashTable.prototype.remove = function(key) {
                var position = loseloseHashCode(key);
                if (this.table[position] !== undefined) {
                    if (this.table[position].key === key) {
                        this.table[position] = undefined;
                        return true;
                    } else {
                        var index = position + 1;
                        while ((this.table[index] === undefined) || (this.table[index].key !== key)) {
                            index++;
                        }
                        if (this.table[index].key === key) {
                            this.table[index] = undefined;
                            return true;
                        }
                    }
                } else {
                    return false;
                }
            };
        }
    }
    var hash = new HashTable();
    hash.put("Gandalf", "gandalf@email.com");
    hash.put("John", "johnsnow@email.com");
    //下面兩個(gè)hash值相同
    hash.put("Aaron", "huang@gmail.com");
    hash.put("Tyrion", "tyrion@email.com");
    console.log(hash.get("Gandalf")); //gandalf@email.com
    console.log(hash.get("Loiane")); //undefined
    console.log(hash.remove("Gandalf")); //true
    console.log(hash.get("Gandalf")); //undefined
源碼地址

Javascript的數(shù)據(jù)結(jié)構(gòu)與算法(二)源碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/86660.html

相關(guān)文章

  • 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)算法):鏈表

    摘要:實(shí)現(xiàn)移除給定的元素要移除的元素返回值表示移除成功方法說(shuō)明移除單向鏈表中某個(gè)位置的元素。的前端樂(lè)園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法二鏈表 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(三):集合第四篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與...

    lolomaco 評(píng)論0 收藏0
  • CSS技巧

    摘要:技巧使你的更加專(zhuān)業(yè)這是上關(guān)于技巧的一篇譯文,另外你也可以在本項(xiàng)目看到原文。列舉了一些很實(shí)用的技巧,比如給空內(nèi)容的標(biāo)簽添加內(nèi)容,逗號(hào)分隔列表等等。排序算法看源碼,把它背下來(lái)吧排序算法的封裝。主要幫助初學(xué)者更好的掌握排序算法的實(shí)現(xiàn)。 成為專(zhuān)業(yè)程序員路上用到的各種優(yōu)秀資料、神器及框架 成為一名專(zhuān)業(yè)程序員的道路上,需要堅(jiān)持練習(xí)、學(xué)習(xí)與積累,技術(shù)方面既要有一定的廣度,更要有自己的深度。 Java...

    DangoSky 評(píng)論0 收藏0
  • CSS技巧

    摘要:技巧使你的更加專(zhuān)業(yè)這是上關(guān)于技巧的一篇譯文,另外你也可以在本項(xiàng)目看到原文。列舉了一些很實(shí)用的技巧,比如給空內(nèi)容的標(biāo)簽添加內(nèi)容,逗號(hào)分隔列表等等。排序算法看源碼,把它背下來(lái)吧排序算法的封裝。主要幫助初學(xué)者更好的掌握排序算法的實(shí)現(xiàn)。 成為專(zhuān)業(yè)程序員路上用到的各種優(yōu)秀資料、神器及框架 成為一名專(zhuān)業(yè)程序員的道路上,需要堅(jiān)持練習(xí)、學(xué)習(xí)與積累,技術(shù)方面既要有一定的廣度,更要有自己的深度。 Java...

    zgbgx 評(píng)論0 收藏0
  • 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)算法(四):叉搜索樹(shù)

    摘要:像剛才的這幅圖,就是二叉搜索樹(shù)。而我們本文要學(xué)習(xí)的內(nèi)容,就是如何寫(xiě)一個(gè)二叉搜索樹(shù)。但在二叉搜索樹(shù)中,我們把節(jié)點(diǎn)成為鍵,這是術(shù)語(yǔ)。前端路漫漫,且行且歌的前端樂(lè)園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法四二叉搜索樹(shù) 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)...

    ingood 評(píng)論0 收藏0
  • JavaScript數(shù)據(jù)結(jié)構(gòu)算法) —— 隊(duì)列

    摘要:簡(jiǎn)介隊(duì)列遵循的是先進(jìn)先出的原則的一組有序的項(xiàng)。隊(duì)列從尾部添加新元素,并從頂部移除元素,最新添加的元素必須排列在隊(duì)列的末尾。它的想法來(lái)自于生活中排隊(duì)的策略。隊(duì)列不做任何變動(dòng)。 簡(jiǎn)介 隊(duì)列遵循的是FIFO(先進(jìn)先出)的原則的一組有序的項(xiàng)。 隊(duì)列從尾部添加新元素,并從頂部移除元素,最新添加的元素必須排列在隊(duì)列的末尾。 它的想法來(lái)自于生活中排隊(duì)的策略。顧客在付款結(jié)賬的時(shí)候,按照到來(lái)的先后順序排...

    xingqiba 評(píng)論0 收藏0
  • 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)算法(一):棧隊(duì)列

    摘要:之?dāng)?shù)組操作接下來(lái)就是數(shù)據(jù)結(jié)構(gòu)的第一部分,棧。以字符串顯示棧中所有內(nèi)容方法的實(shí)現(xiàn)說(shuō)明需要往棧中添加新元素,元素位置在隊(duì)列的末尾。的前端樂(lè)園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法,棧與隊(duì)列 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(三):集合第...

    Flink_China 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<