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

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>
            欧美日韩国产一区二区三区| 99热这里只有成人精品国产| 国际精品欧美精品| 一区二区三欧美| 亚洲视频一起| 欧美美女福利视频| 欧美制服第一页| 午夜精品影院| 夜色激情一区二区| 亚洲精品一区二区三| 国产日韩欧美综合在线| 午夜亚洲精品| 欧美精品一区二区在线播放| 亚洲伦理久久| 日韩一级精品视频在线观看| 欧美成人视屏| 国产精品日韩在线一区| 欧美激情免费在线| 久久中文久久字幕| 欧美一区二区视频免费观看| 亚洲一级黄色av| 国产精品手机在线| 红桃视频欧美| 久久综合色播五月| 国产精品人人做人人爽人人添| 亚洲欧美日韩一区二区三区在线观看| 蜜桃av一区二区三区| 亚洲高清av| 午夜欧美电影在线观看| 精品二区久久| 欧美专区日韩视频| 亚洲国产日韩在线一区模特| 久久成人综合视频| 亚洲日韩视频| 亚洲免费视频成人| 欧美综合二区| 亚洲成色777777女色窝| 亚洲国产成人在线播放| 欧美国产精品一区| 亚洲一区视频在线| 欧美日韩一本到| 久久国产99| 国产精品亚洲成人| 亚洲东热激情| 亚洲人精品午夜| 亚洲一区二区欧美日韩| 亚洲一区二区三区影院| 久久精品二区| 久久综合九色| av成人免费在线观看| 欧美成人午夜免费视在线看片| 欧美日本免费一区二区三区| 亚洲午夜一区二区三区| 欧美国产大片| 欧美成人dvd在线视频| 欧美视频你懂的| 久久男人资源视频| 国产精品亚洲视频| 一本综合久久| 一本久道久久综合狠狠爱| 久久综合99re88久久爱| 在线精品一区二区| 久久亚洲一区二区| 蜜桃伊人久久| 亚洲国产高清在线观看视频| 久久久久久久精| 久久综合久久综合这里只有精品| 欧美视频在线观看一区| 夜夜嗨av一区二区三区| 亚洲二区视频| 久久国产精品久久久久久久久久| 久久久久久9| 国产一区二区三区四区| 亚洲欧美日韩中文视频| 欧美一区亚洲| 国产亚洲一区二区精品| 欧美一区三区三区高中清蜜桃| 欧美一级黄色录像| 国产亚洲综合在线| 久久久久久伊人| 女人天堂亚洲aⅴ在线观看| 亚洲第一区在线| 欧美电影免费观看大全| 日韩视频一区二区三区| 亚洲字幕一区二区| 国产欧美日韩在线视频| 久久激情综合网| 欧美a一区二区| 亚洲人体1000| 国产精品久久97| 欧美在线关看| 能在线观看的日韩av| 国产一区二区0| 欧美一区二区高清| 麻豆成人综合网| 国产日韩一区二区三区在线播放| 久久高清国产| 亚洲国内自拍| 欧美一级免费视频| 红桃视频成人| 欧美日本在线视频| 亚洲欧美日韩另类精品一区二区三区 | 午夜国产欧美理论在线播放| 久久aⅴ乱码一区二区三区| 精东粉嫩av免费一区二区三区| 久久深夜福利免费观看| 亚洲日本免费| 久久九九精品99国产精品| 亚洲激情在线| 国产精品美女xx| 蜜桃精品一区二区三区 | 欧美插天视频在线播放| 99精品99久久久久久宅男| 欧美在线亚洲一区| 亚洲最新合集| 久久精品官网| 亚洲天堂av图片| 久久婷婷国产综合国色天香| 亚洲精品男同| 国产日韩欧美在线播放| 欧美片在线观看| 久久精精品视频| 亚洲乱码国产乱码精品精天堂| 久久久久久久久综合| 在线亚洲精品福利网址导航| 激情欧美一区二区三区| 国产精品成人一区二区| 蘑菇福利视频一区播放| 亚洲视频在线观看一区| 亚洲激情啪啪| 欧美ab在线视频| 久久成人精品无人区| 亚洲一二三区在线观看| 亚洲激情图片小说视频| 国产性天天综合网| 欧美日一区二区在线观看| 免费成人黄色av| 欧美在线视频二区| 亚洲一二三级电影| 99精品热6080yy久久| 亚洲国产精品久久久久秋霞蜜臀| 久久精品国产在热久久| 亚洲尤物精选| 极品少妇一区二区三区| 欧美日韩国产美| 欧美激情一二三区| 欧美韩日一区二区三区| 免费在线欧美视频| 免费在线观看一区二区| 久久夜色精品国产亚洲aⅴ| 午夜精品电影| 亚洲免费影视| 亚洲欧美久久久| 亚洲自拍电影| 午夜精品久久久久久| 亚洲欧美激情精品一区二区| 亚洲无人区一区| 亚洲深爱激情| 亚洲一级黄色| 欧美一区国产在线| 亚洲一级片在线观看| 99re6热只有精品免费观看| 亚洲人精品午夜| 日韩一级在线观看| 日韩亚洲欧美中文三级| 亚洲精品一区二区三区婷婷月| 亚洲精品孕妇| 99天天综合性| 亚洲一区二区免费看| 亚洲欧美在线网| 欧美在线看片| 久久综合综合久久综合| 欧美成人精品h版在线观看| 免费亚洲一区二区| 欧美日韩精品久久| 国产精品久久影院| 极品少妇一区二区三区| 国产一区在线视频| 国产一区日韩二区欧美三区| 国产欧美一区视频| 伊大人香蕉综合8在线视| 最新亚洲激情| 亚洲制服av| 久久免费偷拍视频| 亚洲丰满在线| 一区二区三区四区五区在线| 亚洲中字黄色| 另类专区欧美制服同性| 欧美日韩免费网站| 国产亚洲高清视频| 亚洲国产专区校园欧美| 亚洲视频每日更新| 久久久精品免费视频| 欧美高清在线视频观看不卡| 亚洲免费精品| 久久久国产一区二区| 亚洲香蕉网站| 亚洲午夜一区二区三区| 亚洲欧美日韩国产精品| 麻豆成人91精品二区三区|