青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

step by step

 

數(shù)據(jù)結構-散列1

    最近在看Bartosz Milewski的C++ In Action Industrial-Strength Programming Techniques,這本書很不錯,它不是語言基礎教程,全書主要介紹了許多工業(yè)強度的編程技術,如清理,隱藏實現(xiàn)細節(jié),資源管理,共享,資源管理,使用標準模板庫,重載運算符等技術。這是Bartosz Milewski的簡介:Bartosz Milewski,C++ In Action 的作者。是Reliable Software公司的總裁,Reliable Software公司是一家為程序員制造高質量開發(fā)工具的公司。在過去幾年間,Bartosz Milewski在多家知名雜志發(fā)表了大量技術文章。在微軟工程工作的8年期間,他擔任Windows2000中Content Index組件的開發(fā)主管,他曾經(jīng)在波蘭的Wroclaw大學講授C++編程課程,而且他獲得了Wroclaw大學的理論物理學博士學位。 這是他為這本書管理的blog:http://www.relisoft.com/forums/index.php?s=ee4c0dc7cafef9f08c7c18a6e449b424&showforum=3,售后服務還不錯,呵呵,以我目前的水平看起來還挺累的,我想最好把C++ Primer和effective c++,more effective c++看完再看這本書會比較好,不過硬著頭皮看也有好處,就像有時候武俠小說里用非常規(guī)方法提高修為有時候也能起到意想不到的效果。言歸正傳,在這本書中多次用到哈希表,很多地方不明白,查了書整理一下。
   
    散列表(hash table)的實現(xiàn)常稱為散列(hashing),散列是一種用于以常數(shù)平均時間執(zhí)行插入,刪除和查找的技術。但是,那些需要元素間任何排序信息的樹操作不會得到有效的支持。因此諸如findMin,findMax以及在線性時間內按順序打印整個表的操作都是散列所不支持的。
    我們把表的大小記作TableSize,我們把每個鍵映射到從0到TableSize-1這個范圍中的某個數(shù),并且將其放到適當?shù)膯卧小_@個映射就稱為散列函數(shù)(hash function),理想情況下它應該運算簡單并且應該保證任何兩個不同的鍵映射到不同的單元。不過,這是不可能的。因此我們尋找一個散列函數(shù),該函數(shù)要在單元之間均勻分配鍵。這就是散列的基本思想,剩下的問題則是要選擇一個函數(shù),決定當兩個鍵散列到同一個值的時候(稱為(collision))應該做什么以及如何確定散列表的大小。

1.散列函數(shù)
    如果輸入的鍵是整數(shù),一般合理的方法就是直接返回"Key mod Tablesize",但Key具有某些不理想的性質,比如若表的大小是10而鍵的各位都是0。則此時上述標準的散列函數(shù)就不是一個好的選擇,好的辦法通常是保證表的大小是素數(shù),當輸入的鍵是隨機整數(shù)時,散列函數(shù)不僅運算簡單而且鍵的分配也很均勻。
    通常,鍵是字符串;在這種情形下,散列函數(shù)需要仔細選擇。
    一種選擇方法是把字符串中字符的ASCII碼值加起來,下面的例程實現(xiàn)了這種策略。
   

1int hash( const string &key, int tableSize )
2{
3    int hashVal = 0;
4    forint i=0; i<key.length(); i++ )
5        hashVal += key[i];
6    return hashVal % tableSize;
7}

    上述散列函數(shù)實現(xiàn)起來簡單而且能夠很快地算出答案。不過如果表很大,則函數(shù)就不會很好地分配鍵。例如,設TableSize=10007(10007是素數(shù)),并設所有的鍵至多8個字符長,由于ASCII字符的值最多是127,因此散列函數(shù)只能在0-1016之間取值,顯然這不是一種均勻的分配。
    另一個散列函數(shù)如下表示,這個散列函數(shù)假設Key至少三個字符。值27表示英文字母表的字母個數(shù)外加一個空格,而729是27×27,該函數(shù)只考察前三個字符,但是如果它們是隨機的,而表的大小還是10007,那么我們就會得到一個合理的均衡分布。可是,英文不是隨機的。雖然3個字符(忽略空格)有26×26×26=17576種可能的組合,但查驗詞匯量足夠大的聯(lián)機詞典卻揭示出,3個字母的不同組合數(shù)實際上只有2851。即使這些組合沒有沖突,也不過只有表的28%被真正散列到。因此,雖然很容易計算,但是當散列表足夠大的時候這個函數(shù)還是不合適的。

1int hash( const string &key, int tableSize )
2{
3    return (key[0]+27*key[1]+729*key[2]) % tableSize
4}


    下面的例程列出了第3種嘗試。這個散列函數(shù)涉及鍵中的所有字符,并且一般可以分布得很好,程序根據(jù)Horner法則計算一個37的多項式函數(shù)。這個散列函數(shù)利用了允許溢出這個事實。這可能會引進負數(shù),因此在末尾有附加的測試,這個散列函數(shù)就表的分布而言未必是最好的,但是確實具有極其簡單的優(yōu)點而且速度也很快。如果鍵特別長,那么該散列函數(shù)計算起來將會花費過多的時間。在這種情況下通常做法是不使用所有的字符。此時鍵的長度和性質將影響選擇。例如,鍵可能是完整的街道地址,散列函數(shù)可以包括街道地址的幾個字符,或許也包括城市名和郵政編碼的幾個字符。有些程序設計人員通過只使用奇數(shù)位置上的字符來實現(xiàn)他們的散列函數(shù),這里有這么一層想法:用計算散列函數(shù)節(jié)省下的時間來補償由此產(chǎn)生的對均勻分布的函數(shù)的輕微干擾。

 1int hash( const string &key, int tableSize )
 2{
 3    int hashVal = 0;
 4    for(int i=0;i<key.length();i++)
 5        hashVal = 37 * hashVal + key[i];
 6    hashVal %= tableSize;
 7    if( hashVal <0 )
 8        hashVal += tableSize;
 9    return hashVal;
10}

    剩下的主要編程細節(jié)是解決沖突。如果當一個元素在插入時與一個已經(jīng)插入的元素散列到相同的值,那么就產(chǎn)生一個沖突,這個沖突需要消除。



2.分離鏈接法
    解決沖突的第一種方法通常稱為分離鏈接法(separate chaining),其做法是將散列到同一個值的所有元素保留到一個鏈表中,可以使用標準庫中表的實現(xiàn)方法。如果空間很緊,則更可取的方法是避免使用它們(因為這些表是雙向鏈表,浪費空間),為執(zhí)行search,我們使用散列函數(shù)來確定究竟該遍歷那個鏈表,然后查找相應的表。為執(zhí)行insert,我們檢查相應的表來確定是否該元素已經(jīng)在表中了(如果要插入重復元,那么通常要留出一個額外的數(shù)據(jù)成員,當出現(xiàn)匹配事件時這個數(shù)據(jù)成員增1),如果這個元素是個新的元素,那么它將被插入到表的前端,這不僅因為方便,而且還因為最后插入的元素最有可能不久再次被訪問,實現(xiàn)分離鏈接法所需要的類架構在下面的例程中給出。散列表結構存儲一個鏈表數(shù)組,這個數(shù)組在構造函數(shù)中指定。

 1//分離鏈接散列表的類構架
 2template <typename HashedObj>
 3  class HashTable
 4 {
 5public:
 6    explicit HashTable( int size = 101 );
 7
 8    bool contains( const HashedObj &x ) const;
 9
10   void makeEmpty();
11   void insert( const HashedObj x);
12   void remove( const HashedObj x);
13
14 private:
15    vector<list<HashedObj> > theLists;// >>是c++的一個運算符,而且比>長,因此兩個>之間需要一個空格
16    int currentSize;
17    
18    void rehash()
19    int myhash( const HashedObj &x ) const;
20};
21
22int hash( const string &key );
23int hash( int key );
24
25    

    這里不使用那些將對象和類的大小作為參數(shù)的散列函數(shù),而是使用那些僅以對象為參數(shù)的散列函數(shù),并且返回int。散列表類有一個私有的成員函數(shù)myhash,這個函數(shù)將結果分配到一個合適的數(shù)組索引中。

 1int myhash( const HashedObj &x ) const
 2{
 3    int hashVal = hash(x);
 4    hashVal %=theLists.size();
 5    if( hashVal < 0)
 6        hashVal += theLists.size();
 7    return hashVal;
 8}

 9     
10

     下面的例程中列出了一個可以存儲在一般散列表中的Employee類,該類使用name成員作為鍵,Employee類通過提供相等性操作符和一個散列函數(shù)來實現(xiàn)HashedObj的需求。

 1class Employee
 2{
 3public:
 4    const string & getname() const
 5        return name; }
 6    bool operator==const Employee &rhs )  const
 7        return getName() == rhs.getName(); }
 8    bool operator!=const Employee & rhs }
 const
 9        return !(*this == rhs); }
10
11private:
12    string name;
13    double salary;
14    int seniority;
15};
16
17int hash( const Employ &item )
18{
19    return hash( item.getName() );
20}

    實現(xiàn)makeEmpty,contains和remove的程序代碼如下

 1void makeEmpty()
 2 {
 3    forint i=0; i<theLists.size();i++ )
 4        theLists[i].clear();
 5}

 6
 7bool contains( const HashedObj &x ) const
 8{
 9    const list<HashedObj> & whichList = theLists[myhash(x)];
10    return find( whichList.begin(),whichList.end(),x) !=whichList.end();
11}

12
13bool remove( const HashedObj &x )
14{
15    list<HashedObj> &whichList = theLists[myhash(x)];
16    list<HashedObj>::iterator itr = find(whichList.begin(),whichList.end(),x);
17    if( itr == whichList.end() )
18        return false;
19    whichList.erase( itr );
20    --currentSize;
21    return true;
22}

    下一個操作是插入例程。如果要插入的項已經(jīng)存在,那么什么都不做;否則將其放至表的前端。該元素可以放在表的任何地方;此處使用push_back是最方便的。whichList是一個引用變量

 1bool insert ( const HashedObj &x )
 2{
 3    list<HashedObj> & whichList = theLists[ myhash(x) ];
 4    if( find( whichList.begin(),whichList.end(),x )!=whichList.end() )
 5        return false;
 6    whichList.push_back(x);
 7    
 8    if(++currentSize > theLists.size() )
 9        rehash();
10
11    return true;
12}



 

posted on 2009-11-25 22:22 小羅羅 閱讀(842) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導航

統(tǒng)計

常用鏈接

留言簿

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情第4页| 欧美日韩国产成人高清视频| 国产精品初高中精品久久| 亚洲综合国产| 久久久久久国产精品mv| 一二三区精品| 久久久精品国产一区二区三区| 一本久道久久综合婷婷鲸鱼| 欧美影院久久久| 亚洲视频1区| 美女主播视频一区| 久久av一区二区三区| 欧美国内亚洲| 久久这里有精品15一区二区三区| 欧美日韩免费一区二区三区视频| 久久综合久色欧美综合狠狠 | 亚洲高清免费视频| 在线视频精品一区| 亚洲高清在线| 香蕉久久一区二区不卡无毒影院 | 午夜精品影院| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 久久影音先锋| 国产精品实拍| aa级大片欧美三级| 亚洲精品视频一区二区三区| 久久精品欧洲| 久久精品人人做人人爽| 国产精品日韩欧美一区二区| 亚洲精品久久久久久久久| 黑人操亚洲美女惩罚| 午夜精品久久久久久久99黑人| 一区二区三区精品视频在线观看| 久久这里有精品视频| 久久免费午夜影院| 国产午夜精品理论片a级探花| 中文久久精品| 亚洲欧美激情一区| 国产精品久久久久久久第一福利| 日韩视频不卡| 亚洲午夜性刺激影院| 欧美电影免费观看大全| 亚洲国产精品ⅴa在线观看 | 亚洲国产精品黑人久久久| 国产在线精品一区二区中文 | 99精品欧美一区二区三区| 免费成人性网站| 免费观看在线综合| 尤物九九久久国产精品的分类| 久久国产精品一区二区三区| 久久黄色小说| 国产一区二区三区高清播放| 欧美亚洲视频在线看网址| 久久成人免费电影| 国模精品一区二区三区| 久久久久久9| 亚洲国产成人av好男人在线观看| 亚洲激情成人| 欧美日韩视频在线一区二区| 日韩午夜免费视频| 欧美一区二区三区婷婷月色 | 欧美在线关看| 免费观看在线综合色| 亚洲人成在线观看一区二区| 欧美激情一区二区三区不卡| 亚洲免费观看| 久久激情五月激情| 亚洲国产日韩欧美| 欧美三日本三级少妇三99| 亚洲一区免费看| 美女国产一区| 一本色道久久综合亚洲91| 国产精品中文在线| 久久精品一区四区| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲精品久久久久久久久久久| 亚洲一区久久久| 狠狠色2019综合网| 欧美女激情福利| 欧美亚洲午夜视频在线观看| 亚洲第一精品电影| 午夜在线精品偷拍| 亚洲黄色免费电影| 国产精品乱子久久久久| 老司机一区二区| 中文精品视频一区二区在线观看| 久久夜色精品国产亚洲aⅴ| 亚洲精品系列| 国产一区日韩欧美| 欧美日韩一区二区精品| 久久九九精品99国产精品| 亚洲人成小说网站色在线| 香蕉乱码成人久久天堂爱免费 | 亚洲欧美一区二区视频| 亚洲第一精品影视| 欧美一区1区三区3区公司| 最新热久久免费视频| 国产婷婷色一区二区三区四区| 欧美激情按摩| 久久九九99| 亚洲欧美成人一区二区在线电影| 欧美国产一区在线| 久久久久久有精品国产| 亚洲在线黄色| 91久久精品国产91性色| 久久一区二区三区av| 国产精品爽黄69| 久久亚洲一区二区三区四区| 日韩亚洲欧美综合| 免费观看日韩| 欧美在线啊v一区| 欧美成人免费大片| 亚洲欧美成aⅴ人在线观看| 亚洲国产精品免费| 国产欧美日韩视频在线观看| 欧美韩日一区二区三区| 久久精品一区二区三区不卡牛牛| 亚洲视频一区在线| 亚洲免费激情| 亚洲国产欧洲综合997久久| 久久精品中文字幕免费mv| 亚洲女同在线| 在线综合亚洲欧美在线视频| 亚洲激情小视频| 亚洲成人在线观看视频| 国产在线精品成人一区二区三区| 国产精品二区影院| 欧美日韩亚洲成人| 欧美精品午夜视频| 欧美激情bt| 欧美激情综合色| 欧美福利影院| 欧美激情一区二区三区在线视频| 蜜桃av一区二区三区| 免费欧美电影| 欧美激情1区2区| 欧美精品久久久久久久久老牛影院 | 久久爱另类一区二区小说| 午夜天堂精品久久久久 | 一区二区三区蜜桃网| 日韩特黄影片| 中文av一区特黄| 亚洲亚洲精品在线观看| 亚洲一区二区欧美| 亚洲欧美伊人| 久久精品噜噜噜成人av农村| 久久精品国产第一区二区三区最新章节 | 91久久久久久久久久久久久| 亚洲第一精品福利| 亚洲精品久久久久| 在线午夜精品| 卡一卡二国产精品| 一区二区三区久久久| 亚洲色图综合久久| 亚洲欧美日韩区| 欧美在线啊v| 欧美69视频| 亚洲国产一区在线观看| 亚洲美女色禁图| 亚洲一区二区成人在线观看| 欧美亚洲一区二区三区| 玖玖玖国产精品| 欧美日韩国产欧美日美国产精品| 国产精品成人va在线观看| 国产日产高清欧美一区二区三区| 国产亚洲欧美日韩精品| 亚洲国产日韩美| 亚洲一区二区三区高清| 久久久91精品国产| 亚洲黄色尤物视频| 亚洲欧美999| 麻豆av一区二区三区| 欧美日韩综合| 一区一区视频| 亚洲欧美另类在线观看| 毛片基地黄久久久久久天堂| 亚洲精品欧洲| 久久国产精品72免费观看| 欧美人在线视频| 国内久久精品视频| 亚洲午夜精品一区二区三区他趣| 久久精品首页| 日韩视频免费观看高清完整版| 欧美一区二区成人6969| 欧美高清视频在线观看| 国产日韩欧美三级| 久久久久久九九九九| 久久久精品日韩| 欧美日韩视频在线一区二区| 国产一区二区精品久久99| av不卡在线观看| 久久综合久久综合这里只有精品| 亚洲精品久久久久久久久久久久| 欧美亚洲一区二区三区| 欧美日韩日日骚| 欧美一区二区精品| 亚洲黄色影片| 久久婷婷国产综合国色天香| 国产精品久久久久久久久久直播| 亚洲日本免费|