哈希表 05 實現(xiàn)自己的哈希表

實現(xiàn)思路

  • 維護一個M個元素的數(shù)組泰讽,數(shù)組的每一格掛一棵紅黑樹甜紫;
  • 一個元素進來松嘶,先根據(jù)key計算出其要掛載到哪棵紅黑樹中艘狭;
  • 確定了要掛載的紅黑樹后,問題就變成了在紅黑樹中添加喘蟆,刪除等操作了缓升;
  • M越小鼓鲁,哈希沖突的概率就越大蕴轨,所以M的大小很大程度的影響了哈希表的效率;
import java.util.TreeMap;

public class HashTable<K, V> {

    private TreeMap<K, V>[] hashtable;
    private int size;
    private int M;

    public HashTable(int M){
        this.M = M;
        size = 0;
        hashtable = new TreeMap[M];
        for(int i = 0 ; i < M ; i ++)
            hashtable[i] = new TreeMap<>();
    }

    public HashTable(){
        this(97);
    }

    private int hash(K key){
        return (key.hashCode() & 0x7fffffff) % M;
    }

    public int getSize(){
        return size;
    }

    public void add(K key, V value){
        TreeMap<K, V> map = hashtable[hash(key)];
        if(map.containsKey(key))
            map.put(key, value);
        else{
            map.put(key, value);
            size ++;
        }
    }

    public V remove(K key){
        V ret = null;
        TreeMap<K, V> map = hashtable[hash(key)];
        if(map.containsKey(key)){
            ret = map.remove(key);
            size --;
        }
        return ret;
    }

    public void set(K key, V value){
        TreeMap<K, V> map = hashtable[hash(key)];
        if(!map.containsKey(key))
            throw new IllegalArgumentException(key + " doesn't exist!");

        map.put(key, value);
    }

    public boolean contains(K key){
        return hashtable[hash(key)].containsKey(key);
    }

    public V get(K key){
        return hashtable[hash(key)].get(key);
    }
}

哈希表性能測試

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        System.out.println("Pride and Prejudice");
        ArrayList<String> words = new ArrayList<>();
        if(FileOperation.readFile("pride-and-prejudice.txt", words)) {
            System.out.println("Total words: " + words.size());

            // Test BST
            long startTime = System.nanoTime();

            BST<String, Integer> bst = new BST<>();
            for (String word : words) {
                if (bst.contains(word))
                    bst.set(word, bst.get(word) + 1);
                else
                    bst.add(word, 1);
            }

            for(String word: words)
                bst.contains(word);

            long endTime = System.nanoTime();
            double time = (endTime - startTime) / 1000000000.0;
            System.out.println("BST: " + time + " s");


            // Test AVL
            startTime = System.nanoTime();

            AVLTree<String, Integer> avl = new AVLTree<>();
            for (String word : words) {
                if (avl.contains(word))
                    avl.set(word, avl.get(word) + 1);
                else
                    avl.add(word, 1);
            }

            for(String word: words)
                avl.contains(word);

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("AVL: " + time + " s");


            // Test RBTree
            startTime = System.nanoTime();

            RBTree<String, Integer> rbt = new RBTree<>();
            for (String word : words) {
                if (rbt.contains(word))
                    rbt.set(word, rbt.get(word) + 1);
                else
                    rbt.add(word, 1);
            }

            for(String word: words)
                rbt.contains(word);

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("RBTree: " + time + " s");


            // Test HashTable
            startTime = System.nanoTime();

            // HashTable<String, Integer> ht = new HashTable<>();
            HashTable<String, Integer> ht = new HashTable<>(131071);
            for (String word : words) {
                if (ht.contains(word))
                    ht.set(word, ht.get(word) + 1);
                else
                    ht.add(word, 1);
            }

            for(String word: words)
                ht.contains(word);

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("HashTable: " + time + " s");
        }

        System.out.println();
    }
    
}

輸出:

  • 哈希表要稍微有點優(yōu)勢骇吭;

Pride and Prejudice
Total words: 125901
BST: 0.1774385 s
AVL: 0.0993948 s
RBTree: 0.0992375 s
HashTable: 0.0919606 s

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末橙弱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子燥狰,更是在濱河造成了極大的恐慌棘脐,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件龙致,死亡現(xiàn)場離奇詭異蛀缝,居然都是意外死亡,警方通過查閱死者的電腦和手機目代,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門屈梁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗤练,“玉大人,你說我怎么就攤上這事在讶∩诽В” “怎么了?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵构哺,是天一觀的道長革答。 經(jīng)常有香客問我,道長曙强,這世上最難降的妖魔是什么残拐? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮碟嘴,結(jié)果婚禮上蹦骑,老公的妹妹穿的比我還像新娘。我一直安慰自己臀防,他們只是感情好眠菇,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著袱衷,像睡著了一般捎废。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上致燥,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天登疗,我揣著相機與錄音,去河邊找鬼嫌蚤。 笑死辐益,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的脱吱。 我是一名探鬼主播智政,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箱蝠!你這毒婦竟也來了续捂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤宦搬,失蹤者是張志新(化名)和其女友劉穎牙瓢,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體间校,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡矾克,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了憔足。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胁附。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡差购,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汉嗽,到底是詐尸還是另有隱情欲逃,我是刑警寧澤,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布饼暑,位于F島的核電站稳析,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏弓叛。R本人自食惡果不足惜彰居,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撰筷。 院中可真熱鬧陈惰,春花似錦、人聲如沸毕籽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽关筒。三九已至溶握,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒸播,已是汗流浹背睡榆。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袍榆,地道東北人胀屿。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像包雀,于是被迫代替她去往敵國和親宿崭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系馏艾,并對這種結(jié)構(gòu)定義相應(yīng)的運算劳曹,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,710評論 0 13
  • 這篇文章由一個簡單的問題引出: 有兩個字典,分別存有 100 條數(shù)據(jù)和 10000 條數(shù)據(jù)琅摩,如果用一個不存在的 k...
    多喝水JS閱讀 596評論 0 11
  • Map 是一種很常見的數(shù)據(jù)結(jié)構(gòu)房资,用于存儲一些無序的鍵值對。在主流的編程語言中檀头,默認就自帶它的實現(xiàn)轰异。C岖沛、C++ 中的...
    一縷殤流化隱半邊冰霜閱讀 9,257評論 23 67
  • 有兩個字典,分別存有 100 條數(shù)據(jù)和 10000 條數(shù)據(jù)搭独,如果用一個不存在的 key 去查找數(shù)據(jù)婴削,在哪個字典中速...
    和風(fēng)細羽閱讀 2,346評論 0 5
  • 我在辦公室和同事討論工作,我的語氣有點高高在上牙肝“λ祝慧子來了上海,在旁邊看著我配椭,后來我發(fā)現(xiàn)Y背著書包也來了虫溜。但我沒顧上...
    七未笙閱讀 115評論 0 0