国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 數(shù)據(jù)結(jié)構(gòu)哈希表怎么設(shè)計(jì)及實(shí)現(xiàn)

數(shù)據(jù)結(jié)構(gòu)哈希表怎么設(shè)計(jì)及實(shí)現(xiàn) 時(shí)間:2018-01-26      來源:未知

數(shù)據(jù)結(jié)構(gòu)一直都是軟件工程師必備技能之一,也是難點(diǎn)之一。數(shù)據(jù)結(jié)構(gòu)其實(shí)是數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),它采用不同的存儲(chǔ)方式和邏輯思路,實(shí)現(xiàn)各種數(shù)據(jù)和數(shù)據(jù)之間的關(guān)聯(lián),并且加上對(duì)應(yīng)的算法,來解決問題。哈希表(散列表)是數(shù)據(jù)結(jié)構(gòu)中一種散列存儲(chǔ)方式,優(yōu)點(diǎn)在于關(guān)鍵值key可以通過指定的算法直接得到數(shù)據(jù)的存儲(chǔ)位置hash(key),這樣一來不需要輪詢,時(shí)間復(fù)雜度大大的降低。從而,哈希表滿足了對(duì)數(shù)據(jù)操作高效率的要求。但是,哈希表也不是全能的,它的使用有一定的局限性。下面我們來介紹一下哈希表的設(shè)計(jì)和實(shí)現(xiàn)。

哈希表的設(shè)計(jì)

哈希表主要是確認(rèn)關(guān)鍵值key和關(guān)鍵值存儲(chǔ)位置hash(key)之間的具體關(guān)聯(lián)算法。并且保證少的哈希沖突(多個(gè)不同數(shù)據(jù)通過算法得到存儲(chǔ)位置相同,這時(shí)就是哈希沖突)產(chǎn)生。常見的哈希表的設(shè)置方法如下:

(1)直接定址法:直接的構(gòu)造哈希表的方法,存儲(chǔ)位置是通過線性函數(shù)得到的:

hash(key) = a * key + b {a、b為常數(shù)}

特點(diǎn):這樣得到的 hash(key) 和 key之間一一對(duì)應(yīng),一般不會(huì)產(chǎn)生沖突;

空間:這的哈希表要求地址空間大小與key集合大小相同;

應(yīng)用:一般用于有序的key集合,例如各種編號(hào)。

(2)數(shù)字分析法: 分析已有數(shù)據(jù)的特點(diǎn),選擇盡量沖突少的數(shù)字來構(gòu)造哈希表。

特點(diǎn):數(shù)據(jù)是多位組成,數(shù)據(jù)和數(shù)據(jù)之間有相同的也有不同的,根據(jù)數(shù)據(jù)中每位的分布特點(diǎn),選取若干位作為哈希表地址。

空間:根據(jù)選擇的位的個(gè)數(shù)而定;

應(yīng)用:數(shù)據(jù)位數(shù)多,且都相似, 例如生日,日期等等。

(3)除留余數(shù)法:n個(gè)數(shù)據(jù),選取一個(gè)接近于n的質(zhì)數(shù)p,這時(shí)哈希地址公式:

hash(key) = key % p 除法后得到的余數(shù)就是數(shù)據(jù)存儲(chǔ)位置

特點(diǎn):余數(shù)的取值范圍 0 到 p-1 內(nèi),這樣存儲(chǔ)數(shù)據(jù)空間大小是固定的 p 個(gè);

空間:p個(gè)存儲(chǔ)空間;

應(yīng)用: 數(shù)據(jù)值較大,數(shù)據(jù)個(gè)數(shù)較少。

(4)乘余取整法:先讓關(guān)鍵值key乘上一個(gè)常數(shù)A(0 <1),提取乘積的小數(shù)部分。然后再用整數(shù)n乘以這個(gè)值,對(duì)結(jié)果向下取整,這個(gè)結(jié)果就是存儲(chǔ)位置。<>

公式:hash(key) = (int)((((float)key*A) - (int)(key*A))*n)

應(yīng)用:數(shù)據(jù)是小數(shù),并且相差很少。

(5)平方取中法:一般哈希地址位置數(shù)據(jù)2的某次冪,例如:哈希地址總數(shù)為 m = 2^r。哈希地址hash(key) = 2^key 值中間的r位。

(6)折疊法:數(shù)據(jù)信息很長,可以將數(shù)據(jù)從左到有分成幾個(gè)部分,每部分位數(shù)應(yīng)與hash(key)存儲(chǔ)位置的位數(shù)相同,將每部分都疊加求和,這個(gè)和就是hash(key)存儲(chǔ)位置。

應(yīng)用:例如:圖書館中圖書的標(biāo)準(zhǔn)編號(hào)。

(7)隨機(jī)數(shù)法:獲取一個(gè)隨機(jī)數(shù),作為存儲(chǔ)位置,公式:hash(key) = random(key);

應(yīng)用:key關(guān)鍵字長度不等時(shí)使用。

哈希表的實(shí)現(xiàn)

這里我們以第三種方式除留余數(shù)法舉例。

例子:已知存在以下數(shù)據(jù) : 23 , 26 , 29 ,30,34 ,40

利用哈希表存儲(chǔ)上面數(shù)據(jù),并寫出查找方法。

第一步:確認(rèn)hash(key)和key之間的關(guān)聯(lián)公式

數(shù)據(jù)有6個(gè),先選取一個(gè)質(zhì)數(shù)p = 7 或 11或 13

為盡量減少哈希沖突,當(dāng)選擇p=7時(shí):余數(shù)2 5 1 2 6 5有沖突

當(dāng)選擇p=11時(shí):余數(shù)1 4 7 8 1 6有沖突

當(dāng)選擇p=13時(shí):余數(shù)10 0 3 4 8 1無沖突

所以公式:hash(key) = key % 13;

實(shí)現(xiàn)代碼:
#include<stdio.h>
typedef int data_t;
#define M 13
int emptyHash(data_t *p)  // 判斷哈希地址中是否空閑
{
         return *p == 0 ? 1:0;
}
int setHash(data_t *hp,data_t key)
{
         int i = key % M;
         if(emptyHash(&hp[i]))      // 判讀指定位置是否空閑
                   hp[i] = key;                  // 存儲(chǔ)到哈希表中
         else 
return 0;       // 失敗
         return 1;           // 成功
}
int getHash(data_t *hp,data_t key)
{
         int i = key % M;
         if(hp[i] != key)    
         {
                   printf("數(shù)據(jù)沒有存儲(chǔ)到哈希表中\(zhòng)n");
                   return 0;
         }
         else
                   printf("數(shù)據(jù)在哈希表中,位置%d --> %d\n",i, hp[i]);
         return 1;
}
int main()
{
         data_t hash[13] = {0};          // 定義一個(gè)哈希表(數(shù)組)存儲(chǔ)數(shù)據(jù)空間
         setHash(hash,23);
         setHash(hash,26);
         setHash(hash,29);           // 哈希表中存入數(shù)據(jù)
         setHash(hash,30);
         setHash(hash,34);
         setHash(hash,40);
         getHash(hash,34);           // 查找哈希表
         getHash(hash,32);                    
         return 0;
}

上一篇:嵌入式系統(tǒng)移植步驟

下一篇:嵌入式linux啟動(dòng)過程分析

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部