成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

數(shù)據(jù)結(jié)構(gòu)-散列

lei___ / 2406人閱讀

摘要:散列是一種常用的數(shù)據(jù)存儲(chǔ)技術(shù)散列后的數(shù)據(jù)可以快速的插入或取用散列使用的數(shù)據(jù)結(jié)構(gòu)叫做散列表在散列表上插入刪除和取用的數(shù)據(jù)都非??斓菍?duì)于查找操作來(lái)說(shuō)卻效率低下比如查找一組數(shù)據(jù)中最大值和最小值這些操作得求助于其它數(shù)據(jù)結(jié)構(gòu)二叉查找樹就是一個(gè)很好的

散列是一種常用的數(shù)據(jù)存儲(chǔ)技術(shù), 散列后的數(shù)據(jù)可以快速的插入或取用. 散列使用的數(shù)據(jù)結(jié)構(gòu)叫做 散列表 . 在散列表上插入、刪除和取用的數(shù)據(jù)都非??? 但是對(duì)于查找操作來(lái)說(shuō)卻效率低下, 比如查找一組數(shù)據(jù)中最大值和最小值. 這些操作得求助于其它數(shù)據(jù)結(jié)構(gòu), 二叉查找樹就是一個(gè)很好的選擇. 本章介紹如何實(shí)現(xiàn)散列, 以及了解什么時(shí)候應(yīng)用散列存取數(shù)據(jù).
散列概覽

我們的散列表示基于數(shù)組進(jìn)行設(shè)計(jì)的. 數(shù)組的長(zhǎng)度是預(yù)先設(shè)定的, 如有需要, 可以隨時(shí)增加. 所有元素根據(jù)和該元素對(duì)應(yīng)的鍵, 保存在數(shù)組的特定位置, 該鍵和我們前面講到的字典中的鍵是類似的概念. 使用散列表存儲(chǔ)數(shù)據(jù)時(shí), 通過(guò)一個(gè)散列函數(shù)將鍵映射為一個(gè)數(shù)字, 這個(gè)數(shù)字的范圍是0到散列表的長(zhǎng)度.

理想情況下, 散列函數(shù)會(huì)將每個(gè)鍵映射為一個(gè)唯一的函數(shù)索引. 然鵝, 鍵的數(shù)量是無(wú)限的, 數(shù)組的長(zhǎng)度是有限的(理論上, 在js中是這樣的). 一個(gè)更現(xiàn)實(shí)的目標(biāo)是讓散列函數(shù)盡量將鍵均勻地映射到數(shù)組中.

即使使用一個(gè)搞笑的散列函數(shù), 仍然存在將兩個(gè)鍵映射成同一個(gè)值的可能, 這樣現(xiàn)象稱為 碰撞(collision) , 當(dāng) 碰撞 發(fā)生時(shí), 我們需要有方法去解決. 本章稍后將詳細(xì)討論如何解決 _碰撞_.

要確定的最后一個(gè)問(wèn)題是: 散列表中的數(shù)組究竟應(yīng)該有多大? 這是編寫散列函數(shù)時(shí)必須要考慮的. 對(duì)數(shù)組大小常見(jiàn)的限制是: 數(shù)組長(zhǎng)度應(yīng)該是一個(gè)質(zhì)數(shù). 在實(shí)現(xiàn)各種散列函數(shù)時(shí), 我們將討論為什么要求數(shù)組長(zhǎng)度為質(zhì)數(shù). 之后, 會(huì)有多種確定數(shù)組大小的策略, 所有的策略都基于處理碰撞的技術(shù), 因此, 我們將討論如何處理碰撞時(shí)對(duì)它們進(jìn)行討論.

HashTable

我們使用一個(gè)類來(lái)表示散列表, 該類包含計(jì)算散列值的方法、向散列中插入數(shù)據(jù)的方法、從散列表中讀取數(shù)據(jù)的方法、顯示散列表中數(shù)據(jù)分布的方法, 以及其它一些可能會(huì)用到的工具方法.

class HashTable {
    constructor() {
        this._table = new Array(137);
    }
    _simpleHash() {

    }
    showDistro() {

    }
    put() {
        
    }
}
選擇一個(gè)散列函數(shù)

散列函數(shù)的選擇依賴于鍵值的數(shù)據(jù)類型. 如何鍵是整型, 最簡(jiǎn)單的散列函數(shù)就是以數(shù)組的長(zhǎng)度對(duì)鍵取余. 在一些情況下, 比如數(shù)組的長(zhǎng)度是10, 而鍵值都是10的倍數(shù)時(shí), 就不推薦使用這種方式了. 這也是數(shù)據(jù)長(zhǎng)度為什么要是質(zhì)數(shù)的原因之一, 就像我們?cè)谏蟼€(gè)構(gòu)造函數(shù)中, 設(shè)定數(shù)組長(zhǎng)度為137一樣. 如何鍵是隨機(jī)的整數(shù), 則散列函數(shù)應(yīng)該更均勻地分布這些鍵. 這種散列方式稱為: 除留余數(shù)法 .

在很多應(yīng)用中, 鍵是字符串類型. 事實(shí)證明, 選擇針對(duì)字符串類型的散列函數(shù)是很難的, 選擇時(shí)必須加倍小心.

乍一看, 將字符串中的每個(gè)字符的ASCII碼值相加似乎是一個(gè)不錯(cuò)的散列函數(shù). 這樣散列值就是ASCII碼值的和 除以數(shù)組長(zhǎng)度的余數(shù). 該散列的方法_simpleHash():

...
_simpleHash(data) {
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += data.charCodeAt(i);
        };

        return total % this._table.length;
    }
...

再給HashTable加兩個(gè)方法: put()_showDistro(), 一個(gè)用來(lái)將數(shù)據(jù)存入散列表, 一個(gè)用來(lái)顯示散列表中的數(shù)據(jù), 這樣就初步實(shí)現(xiàn)了HashTable類.

...
showDistro() {
    this._table.forEach((i, index) => {
        if(i != undefined) {
            log(`${index}: ${i}`)
        }
    })
}
put(data) {
    const pos = this._simpleHash(data);
    this._table[pos] = data;
}
...

做一個(gè)簡(jiǎn)單散列:

window.log = console.log.bind(console)

class HashTable {
    constructor() {
        this._table = new Array(137);
    }
    _simpleHash(data) {
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += data.charCodeAt(i);
        };

        return total % this._table.length;
    }
    showDistro() {
        this._table.forEach((i, index) => {
            if(i != undefined) {
                log(`${index}: ${i}`)
            }
        })
    }
    put(data) {
        const pos = this._simpleHash(data);
        this._table[pos] = data;
    }
};

const someNames = [ "David", "Jennifer", "Donnie", "Raymond", "Cynthia", "Mike", "Clayton", "Danny", "Jonathan" ];
const h = new HashTable();
someNames.forEach(i => {
    h.put(i);
});
h.showDistro();

輸出如下:

35: Cynthia
45: Clayton
57: Donnie
77: David
95: Danny
116: Mike
132: Jennifer
134: Jonathan

_simpleHash()函數(shù)通過(guò)使用JScharCodeAt()函數(shù), 返回每個(gè)字符的ASCII碼值, 然后再將它們相加得到散列值. put()方法通過(guò)調(diào)用_simpleHash()函數(shù)得到數(shù)組的索引, 然后將數(shù)據(jù)存儲(chǔ)到該索引對(duì)應(yīng)的位置上. 你會(huì)發(fā)現(xiàn), 數(shù)據(jù)并不是均勻分布的, 人名想數(shù)組的兩端集中.

比起這種不均勻的分布, 還有一個(gè)更嚴(yán)重的問(wèn)題. 如果你仔細(xì)觀察輸出, 會(huì)發(fā)現(xiàn)初始的數(shù)組中的人名并沒(méi)有全部顯示. 給_simpleHash()函數(shù)加入一條console.log()輸出,
log("Hash value:" + data + "->" + total);
運(yùn)行程序你就會(huì)發(fā)現(xiàn)有兩個(gè)字符串"Clayton"和"Raymond"的散列值是一樣的. 一樣的散列值引發(fā)了碰撞, 因?yàn)榕鲎? 只有"Clayton"存入了散列表. 可以通過(guò)改善散列函數(shù)來(lái)避免碰撞.

一個(gè)更好的散列函數(shù)

為了避免碰撞, 首先要確保散列表中用來(lái)存儲(chǔ)數(shù)據(jù)的數(shù)組其大小是個(gè) 質(zhì)數(shù). 這一點(diǎn)很關(guān)鍵, 這和計(jì)算散列值時(shí)使用的取余運(yùn)算有關(guān). 數(shù)組的長(zhǎng)度應(yīng)該在100以上, 這是為了讓數(shù)據(jù)在散列表中分布得更加均勻. 通過(guò)試驗(yàn)我們發(fā)現(xiàn), 比100大且不會(huì)讓數(shù)據(jù)產(chǎn)生碰撞的第一個(gè)質(zhì)數(shù)是137. 使用其它更接近100的質(zhì)數(shù), 在該數(shù)據(jù)集上依然會(huì)產(chǎn)生碰撞.

為了避免碰撞, 在給散列表一個(gè)合適的大小后, 接下來(lái)要有一個(gè)計(jì)算散列值的更好方法.
霍納算法 很好的解決了這個(gè)問(wèn)題. 本書不會(huì)過(guò)深入該算法的數(shù)學(xué)細(xì)節(jié), 在此算法中, 新的散列函數(shù)仍然先計(jì)算字符串中各字符的ASCII碼值, 不過(guò)求和時(shí)每次要乘以一個(gè)質(zhì)數(shù). 大多數(shù)算法書建議使用一個(gè)較小的質(zhì)數(shù), 比如31, 但是對(duì)于我們的數(shù)據(jù)集, 31不起作用, 我們使用37, 這樣剛好不會(huì)產(chǎn)生碰撞.

_betterHash(data) {
    const H = 37;
    let total = 0;
    for(let i = 0; i < data.length; i++) {
        total += H * total + data.charCodeAt(i);
    };
    total = total % this._table.length;
    if(total < 0) {
        total += this._table.length - 1;
    };
    
    return parseInt(total);
}
window.log = console.log.bind(console)

class HashTable {
    constructor() {
        this._table = new Array(137);
    }
    _simpleHash(data) {
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += data.charCodeAt(i);
        };

        return total % this._table.length;
    }
    _betterHash(data) {
        const H = 37;
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += H * total + data.charCodeAt(i);
        };
        total = total % this._table.length;
        if(total < 0) {
            total += this._table.length - 1;
        };
        
        return parseInt(total);
    }
    showDistro() {
        this._table.forEach((i, index) => {
            if(i != undefined) {
                log(`${index}: ${i}`)
            }
        })
    }
    put(data) {
        const pos = this._betterHash(data);
        this._table[pos] = data;
    }
};

const someNames = [ "David", "Jennifer", "Donnie", "Raymond", "Cynthia", "Mike", "Clayton", "Danny", "Jonathan" ];
const h = new HashTable();
someNames.forEach(i => {
    h.put(i);
});
h.showDistro();

程序輸出:

12: Jennifer
22: Raymond
55: Donnie
58: Clayton
80: Jonathan
82: Mike
103: Cynthia
110: Danny

這次所有的人名都顯示出來(lái)了, 而且沒(méi)有碰撞.

散裂化整型鍵

上面展示了如何散列化字符串類型的鍵, 接下來(lái)介紹如何使用散列化整型鍵, 使用的數(shù)據(jù)集是學(xué)生的成績(jī). 我們將隨機(jī)產(chǎn)生一個(gè)9位數(shù)的鍵, 用以識(shí)別學(xué)生身份和一門成績(jī). 下面是產(chǎn)生學(xué)生數(shù)據(jù)(包含ID和成績(jī))的函數(shù):

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

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

使用getRandomInt()函數(shù)時(shí), 可以指定隨機(jī)數(shù)的最大值和最小值. 拿學(xué)生成績(jī)來(lái)說(shuō), 最低分50, 最高分100.

genStuData()函數(shù)生成學(xué)生的數(shù)據(jù). 里層的循環(huán)用來(lái)生成學(xué)生的ID, 緊跟在循環(huán)后面的代碼生成一個(gè)隨機(jī)的成績(jī), 并把成績(jī)綴在ID的后面. 主程序會(huì)把ID和成績(jī)分離. 散列函數(shù)將學(xué)生ID里的數(shù)字相加, 使用_simpleHash()函數(shù)計(jì)算出散列值.

執(zhí)行程序:

const students = new Array(10);
genStuData(students);
students.forEach(i => {
    log(i.substring(0, 8) + "  " + i.substring(9))
});

const h = new HashTable();
students.forEach(i => {
    h.put(i)
});
h.showDistro();

程序輸出:

83700897  87
25732026  56
60875817  85
49919842  77
09796486  57
67922868  58
57820350  58
70903358  54
46307166  100
09033369  99
23: 57820350058
25: 70903358154
27: 25732026956
38: 09033369799
41: 49919842177
46: 09796486557
49: 67922868858
62: 463071660100

散列函數(shù)再一次發(fā)生碰撞, 數(shù)組中沒(méi)有包含所有的數(shù)據(jù). 事實(shí)上, 如果將程序多跑幾次, 有時(shí)會(huì)出現(xiàn)正常的情況, 但是結(jié)果太不一致了. 可以通過(guò)修改數(shù)組的大小, 或者在調(diào)用put()方法時(shí)使用更好的_betterHash()函數(shù), 來(lái)試試能不能解決碰撞.
使用_betterHash()散列函數(shù)得到的輸出:

88200007  99
22314764  82
25636690  64
88623060  53
17940629  70
59142776  58
14774034  70
90261540  66
02406002  75
95463920  65
8: 59142776758
27: 22314764782
46: 95463920165
57: 25636690564
78: 90261540066
80: 88623060453
98: 17940629670
108: 14774034770
112: 02406002475
114: 88200007799

很明顯: 無(wú)論是字符串還是整型, _betterHash()的散列效果都更勝一籌.

對(duì)散列表排序、從散列表中取值

前面講的是散列函數(shù), 現(xiàn)在學(xué)以致用, 看看如何使用散列表來(lái)存儲(chǔ)數(shù)據(jù). 為此, 需要修改put()方法, 使得該方法同時(shí)接受鍵和數(shù)據(jù)作為參數(shù), 對(duì)鍵值散列后, 將數(shù)據(jù)存儲(chǔ)到散列表中.

然后定義get()方法, 用以讀取存儲(chǔ)在散列表中的數(shù)據(jù). 該方法同樣需要對(duì)鍵值進(jìn)行散列化, 然后才能知道數(shù)據(jù)到底存儲(chǔ)在數(shù)組的什么位置.

window.log = console.log.bind(console)

class HashTable {
    constructor() {
        this._table = new Array(137);
    }
    _simpleHash(data) {
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += data.charCodeAt(i);
        };

        return total % this._table.length;
    }
    _betterHash(data) {
        const H = 37;
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += H * total + data.charCodeAt(i);
        };
        total = total % this._table.length;
        if(total < 0) {
            total += this._table.length - 1;
        };
        
        return parseInt(total);
    }
    showDistro() {
        this._table.forEach((i, index) => {
            if(i != undefined) {
                log(`${index}: ${i}`)
            }
        })
    }
    put(key, data) {
        const pos = this._betterHash(key);
        this._table[pos] = data;
    }
    get(key) {
        return this._table[this._betterHash(key)];
    }
};

const h = new HashTable();
h.put("張三", 110);
h.put("李四", 112);
h.put("王五", 119);

log(h.get("王五")); // 輸出 119
碰撞處理

當(dāng)散列函數(shù)對(duì)于多個(gè)輸入產(chǎn)生同樣的輸出時(shí), 就產(chǎn)生了碰撞. 散列算法的第二部分就是介紹如何解決碰撞, 是所有鍵都得以存儲(chǔ)在散列表中. 下面介紹兩種解決辦法: 開鏈法線性探測(cè)法 .

開鏈法

當(dāng)碰撞發(fā)生時(shí), 我們?nèi)韵M麑㈡I存儲(chǔ)到通過(guò)散列算法產(chǎn)生的索引位置上, 但實(shí)際上, 不可能將多份數(shù)據(jù)存儲(chǔ)到一個(gè)數(shù)組單元中. 開鏈法是指實(shí)現(xiàn)散列列表的底層數(shù)組中, 每個(gè)數(shù)組元素又是一個(gè)新的數(shù)據(jù)結(jié)構(gòu), 比如另一個(gè)數(shù)組, 這樣就能存儲(chǔ)多個(gè)鍵了.
使用這種技術(shù). 即使兩個(gè)鍵散列后的值相同, 依然被保存在同樣的位置, 只不過(guò)它們?cè)诘诙€(gè)數(shù)組中的位置不一樣罷了.

實(shí)現(xiàn)開鏈法的方法時(shí): 在創(chuàng)建存儲(chǔ)散列過(guò)的鍵值的數(shù)組時(shí), 通過(guò)調(diào)用一個(gè)函數(shù)創(chuàng)建一個(gè)新的空數(shù)組, 然后將該數(shù)組賦給散列表里的每個(gè)數(shù)組元素. 這樣就創(chuàng)建了一個(gè)二維數(shù)組. 我們定義了一個(gè)函數(shù)buildChains()函數(shù)用來(lái)創(chuàng)建第二組數(shù)組, 我們也稱這個(gè)數(shù)組為 .
完整代碼:

window.log = console.log.bind(console)

class HashTable {
    constructor() {
        this._table = new Array(137);
    }
    _simpleHash(data) {
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += data.charCodeAt(i);
        };

        return total % this._table.length;
    }
    _betterHash(data) {
        const H = 37;
        let total = 0;
        for(let i = 0; i < data.length; i++) {
            total += H * total + data.charCodeAt(i);
        };
        total = total % this._table.length;
        if(total < 0) {
            total += this._table.length - 1;
        };
        
        return parseInt(total);
    }
    showDistro() {
        this._table.forEach((i, index) => {
            if(i[0] != undefined) {
                log(`${index}: ${i}`)
            }
        });
    }
    buildChains() {
        for(let i = 0; i < this._table.length; i++) {
            this._table[i] = new Array();
        };
    }
    put(key, data) {
        const pos = this._betterHash(key);

        let index = 0;
        if(this._table[pos][index] == undefined) {
            this._table[pos][index] = data;
        } else {
            while(this._table[pos][index] != undefined) {
                ++index
            };
            this._table[pos][index] = data;
        }
    }
    get(key) {
        let index = 0;
        const pos = this._betterHash(key);
        
        while ((this._table[pos][index] != undefined) && (this._table[pos][index] != key)) {
            index += 1;
        };
        if(this._table[pos][index] == key) {
            return this._table[pos][index];
        } else {
            return undefined;
        }
    }
};

const someNames = [ "David", "Jennifer", "Donnie", "Raymond", "Cynthia", "Mike", "Clayton", "Danny", "Jonathan" ];
const h = new HashTable();
h.buildChains();
someNames.forEach(i => {
    h.put(i, i);
});
h.showDistro();

log(h.get("David"))
log(h.get("Jonathan"))

考慮到散列表現(xiàn)在使用多維數(shù)組存儲(chǔ)數(shù)據(jù), 為了更好地顯示使用了開鏈法后鍵值的分布, 修改了showDistor()方法.

重新定義了put(), 將鍵值散列, 散列后的的值對(duì)應(yīng)數(shù)組中的一個(gè)位置, 先嘗試將數(shù)據(jù)放在該位置上的數(shù)組中的第一個(gè)單元格, 如果該單元格已經(jīng)有數(shù)據(jù)了, put()方法會(huì)搜索下一個(gè)位置, 知道找到能放置數(shù)據(jù)的單元格, 并把數(shù)據(jù)存儲(chǔ)進(jìn)去. 這里實(shí)際上可以用this._table[pos].push(data)來(lái)代替, 因?yàn)橥ㄟ^(guò)buildChains()方法已經(jīng)將散列表中的元素修改為二維數(shù)組(鏈).

get()方法先對(duì)鍵值散列, 根據(jù)散列后的值找到散列表中相應(yīng)的位置, 然后搜索該位置上的鏈, 知道找到鍵值. 如果找到, 就將緊跟在鍵值后面的數(shù)據(jù)返回; 如果沒(méi)有, 就返回undefined.

線性探測(cè)法

第二種處理碰撞的方法是 線性探測(cè)法 . 線性探測(cè)法隸屬于一種更一般化的散列技術(shù): _開放尋址散列_. 當(dāng)發(fā)生碰撞時(shí), 線性探測(cè)法檢查散列表中的下一個(gè)位置是否為空. 如果為空, 就將數(shù)據(jù)存入該位置; 如果不為空, 則繼續(xù)查找下一個(gè)位置, 知道找到一個(gè)空的為止. 該技術(shù)是基于這樣一個(gè)事實(shí): 每個(gè)散列表都會(huì)有很多空的單元格, 可以使用他們來(lái)存儲(chǔ)數(shù)據(jù).

當(dāng)存儲(chǔ)數(shù)據(jù)使用的數(shù)組特別大時(shí), 選擇線性探測(cè)法要比開鏈法好. 這里有個(gè)公式, 常常可以幫助我們選擇使用哪種碰撞解決辦法: 如果數(shù)組的大小事帶存儲(chǔ)數(shù)據(jù)個(gè)數(shù)的1.5倍, 那么使用開鏈法; 如果數(shù)組的大小是待存儲(chǔ)數(shù)據(jù)的兩倍及兩倍以上時(shí), 那么使用線性探測(cè)法.

為了說(shuō)明線性探測(cè)法的工作原理, 可以重寫put()get()方法. 為了實(shí)現(xiàn)一個(gè)真實(shí)的數(shù)據(jù)存取系統(tǒng), 需要為HashTable類增加一個(gè)新的數(shù)組, 用來(lái)存儲(chǔ)數(shù)據(jù). 數(shù)組_table_values并行工作, 當(dāng)將一個(gè)鍵值保存到數(shù)組_table中同時(shí)將數(shù)據(jù)存入數(shù)組_values中相應(yīng)的位置上.

HashTable的構(gòu)造函數(shù)中加入下面一行代碼:

this._values = [];

put()方法中使用線性探測(cè)技術(shù):

...
put(key, data) {
    let pos = this._betterHash(key);
    
    if(this._table[pos] == undefined) {
        this._table[pos] = key;
        this._values[pos] = data;
    } else {
        while(this._table[pos] != undefined) {
            pos++
        };
        this._table[pos] = key;
        this._values[pos] = data;
    }
}
...

get()方法先搜索鍵在散列表中的位置, 如果找到, 則返回?cái)?shù)組_values中對(duì)應(yīng)位置上的數(shù)據(jù); 如果沒(méi)有找到, 則循環(huán)搜索, 知道找到對(duì)應(yīng)的鍵或者數(shù)組中的單元為undefined時(shí), 后者表示該鍵沒(méi)有被存入散列表中.

...
get(key) {
    let hash = -1;
    hash = this._betterHash(key);

    if(hash > -1) {
        for(let i = hash; this._table[hash] != undefined; i++) {

            if(this._table[i] === key) {
                return this._values[i];
            };
        }
    };

    return undefined;
}
...

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

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

相關(guān)文章

  • 程序員修仙之路--把用戶訪問(wèn)記錄優(yōu)化到極致

    摘要:散列表用的是數(shù)組支持按照下標(biāo)隨機(jī)訪問(wèn)數(shù)據(jù)的特性,所以散列表其實(shí)就是數(shù)組的一種擴(kuò)展,由數(shù)組演化而來(lái)。我們可以把它定義成,其中表示元素的鍵值,的值表示經(jīng)過(guò)散列函數(shù)計(jì)算得到的散列值。 showImg(https://segmentfault.com/img/remote/1460000018521371?w=833&h=1096); 祝愿大家不要像菜菜這般苦逼,年中獎(jiǎng)大大滴在沒(méi)有年終獎(jiǎng)的日子...

    shevy 評(píng)論0 收藏0
  • Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第四節(jié):散列

    摘要:實(shí)例導(dǎo)入包包與本地進(jìn)行鏈接,地址為,端口號(hào)為和字符串一樣,對(duì)散列中一個(gè)尚未存在的鍵執(zhí)行自增操作時(shí),會(huì)將鍵的值當(dāng)作來(lái)處理。 上一篇文章:Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第三節(jié):集合下一篇文章:Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第五節(jié):有序集合 第一章提到過(guò),Redis的散列可以讓用戶將多個(gè)鍵值對(duì)存儲(chǔ)到一個(gè)Redis里面。從功能上來(lái)說(shuō),Red...

    waterc 評(píng)論0 收藏0
  • js數(shù)據(jù)結(jié)構(gòu)和算法(五)字典和散列(hash)

    摘要:哈希表也是種數(shù)據(jù)結(jié)構(gòu),它可以提供快速的插入操作和查找操作。一個(gè)更好的散列函數(shù)為了避免碰撞,首先要確保散列表中用來(lái)存儲(chǔ)數(shù)據(jù)的數(shù)組其大小是個(gè)質(zhì)數(shù),這和計(jì)算散列值時(shí)使用的取余運(yùn)算有關(guān)。散列函數(shù)將學(xué)生里的數(shù)字相加,使用函數(shù)計(jì)算出散列值。 什么是字典結(jié)構(gòu)? 字典是以鍵值對(duì)形式存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),就像電話號(hào)碼薄里的名字和電話號(hào)碼那樣的一一對(duì)應(yīng)的關(guān)系。 javascript的Object類就是以...

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

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

0條評(píng)論

閱讀需要支付1元查看
<