第六周:Hash Tables

1. separate chaining

  1. 思路

    • 键一个长为M的数组,每一个entry是一个linked-list
    • Hash:给每个key赋予一个整数结余0到M-1的i作为这个key的hash code
    • Insert:插入第i条链(linked-list)的最前面
    • Search:只需要查找第i条链(linked-list)
  2. 分析

    • M太大 => 太多空链
    • M太小 => 链太长
    • 一般:M ~ N/5 => constant-time ops
  3. Java implementation

    public class SeparateChainingHashST<Key, Value>{
     private int M = 97; // number of chains
     private Node[] st = new Node[M];    // array of chains
    
     private static class Node{
         private Object key;
         private Object val;
         private Node next;
    
         public Node(Object key, Object val, Node next){
             this.key = key;
             this.val = val;
             this.next = next;
         }
    
     }
    
     private int hash(Key key){
         return (key.hashCode() & 0x7fffffff) % M;
     }
    
     public Value get(Key key){
         int i = hash(key);
         for(Node x = st[i]; x != null; x = x.next){
             if(key.equals(x.key)){
                 return (Value)x.val;
             }
         }
         return null;
     }
    
     public void put(Key key, Value val){
         int i = hash(key);
         for(Node x = st[i]; x != null; x = x.next){
             if(key.equals(x.key)){
                 x.val = val;
                 return;
             }
         }
         st[i] = new Node(key, val, st[i]);
    
     }
    }
    

2. Linear probing

  1. 思路

    • 用一个长为M的数组st

    • Hash:给每个key赋予一个整数结余0到M-1的 i 作为这个key的hash code

    • Insert:如果st[i]是空的,插入值;如果已经被占了,继续试st[i+1]st[i+2],以此类推

    • Search:找st[i];如果被占但不符合我们要找的key,继续试st[i+1]st[i+2],以此类推

    • 注意:st数组长度M必须大于键值对数量N

  2. 分析

    • M太大 => 太多空的array entries

    • M太小 => search time blows up

    • 一般:\alpha = N/M ~ \frac{1}{2}

      • # probes for search hit is about 3/2

      • # probes for search miss is about 5/2

  3. Java Implementation

    public class LinearProbingHashST<Key, Value>{
     private int M = 30001;
     private Value[] vals = (Value[]) new Object[M];
     private Key[] keys = (Key[]) new Object[M];
    
     private int hash(Key key){
         return (key.hashCode() & 0x7fffffff) % M;
     }
    
     public void put(Key key, Value val){
         int i = 0;
         for(i = hash(key); keys[i] !=null; i = (i+1)%M){
             if(keys[i].equals(key)){
                 break;
             }
         }
         keys[i] = key;
         vals[i] = val;
     }
    
     public Value get(Key key){
         for(int i = hash(key); keys[i] != null; i = (i+1)%M){
             if(key.equals(keys[i])){
                 return vals[i];
             }
         }
         return null;
     }
    }
    
  1. ST implementations: summary

    implemen guarantee average ordered ops? operations on keys
    sequential search (unordered list) Search: N
    insert: N
    delete: N
    Search: N/2
    insert: N
    delete: N/2
    No equals()
    binary search (ordered array) Search: lgN
    insert: N
    delete: N
    Search: lgN
    insert: N/2
    delete: N/2
    Yes compareTo()
    BST Search: N
    insert: N
    delete: N
    Search: 1.39lgN
    insert: 1.39lgN
    delete: \sqrt N
    Yes compareTo()
    Red-black BST Search: 2lgN
    insert: 2lgN
    delete: 2lgN
    Search: lgN
    insert: lgN
    delete: lgN
    Yes compareTo()
    separate chaining Search: lgN
    insert: lgN
    delete: lgN
    Search: 3-5
    insert: 3-5
    delete: 3-5
    No equals()
    hashCode()
    Linear probing Search: lgN
    insert: lgN
    delete: lgN
    Search: 3-5
    insert: 3-5
    delete: 3-5
    No equals()
    hashCode()
  • Separate chaining
    • easier to implement delete
    • performance degrades gracefully
    • clustering less sensitive to poorly-designed hash function
  • Linear probing
    • less wasted space
    • better cache performance
  • Hash tables
    • Simple to code
    • No effective alternative for unordered keys
    • Faster for simple keys
    • Better system support in Java for Strings
    • Hash tables: java.util.HashMapjava.util.IdentityHashMap
  • Baleced search trees
    • Stronger performance guarantee
    • Support for ordered ST operations
    • Easier to implement compareTo() correctly than equals() and hashCode()
    • Red-black BSTs: java.util.TreeMapjava.util.TreeSet
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容