数据结构----HashMap哈希表

作者: pgydbh | 来源:发表于2018-08-21 18:32 被阅读17次

    结构

    数组。
    需要size()----大小
    需要put(k,v)----放入
    需要get(i)----取出

    思路

    ①初始化空间大小为2^n,比如2,4,8,16。
    ②从节点计算hash&(length-1)得到位置插入,之后计算是否超出阈值(这个阈值由自己决定,是否超出阈值决定了要不要扩容)

    对于上面的解释
    ①hash值不确定,可能会特别大,加入长度为16,hash为11111111
    ②00001111&11111111=00001111=15
    ③所有的hash都在当前范围内,但会形成链。
    ④有人分析了很多得出结论----扩容2倍是最好的,避免了数组空间的浪费,充分利用了空间,减少了碰撞的概率。https://blog.csdn.net/jiary5201314/article/details/51439982
    ⑤但是个人觉得选择2倍扩容,并且初始为2的倍数,只是为了处理分配空间,扩容重新排序的正常反应。

    ③如果阈值大于自己的设定值(demo里设最长链长度为b,空间大小为2^n,当b>n)
    ④新建一个长度为当前二倍的数组空间,数据整理到新的数组中。hashmap的数组变更为新的数组。
    ⑤继续插入。

    代码

    
    public class HashMap<K, V> {
    
        private Node<K, V>[] nodes = new Node[2];
        private int len = 2;
        private int mi = 1;
        private int size;
        private int branch;
    
        public int size(){
            return size;
        }
    
        public void put(K k, V v){
            int temp = (len - 1) & k.hashCode();
            if (nodes[temp] == null){
                nodes[temp] = new Node<>(k, v);
            } else {
                Node node = nodes[temp];
                int i = 1;
                while (node != null){
                    i++;
                    if (node.k.equals(k)){
                        node.v = v;
                        size--;
                        break;
                    }
                    if (node.next == null){
                        node.next = new Node(k, v);
                        break;
                    }
                    node = node.next;
                }
                if (i > branch) {
                    branch = i;
                }
            }
            size++;
            if (branch > mi && mi < 31){
                sort();
            }
        }
    
        //内部整理put
        private void put(Node[] nodes, K k, V v){
            int temp = (nodes.length - 1) & k.hashCode();
            if (nodes[temp] == null){
                nodes[temp] = new Node<>(k, v);
            } else {
                Node node = nodes[temp];
                while (node != null){
                    if (node.k.equals(k)){
                        node.v = v;
                        size--;
                        break;
                    }
                    if (node.next == null){
                        node.next = new Node(k, v);
                        break;
                    }
                    node = node.next;
                }
            }
        }
    
        public V get(K k){
            int temp = k.hashCode() & (len - 1);
            if (temp < size && temp >= 0){
                Node node = nodes[temp];
                while (node != null) {
                    if (node.k.equals(k)){
                        return (V) node.v;
                    }
                    node = node.next;
                }
            }
            return null;
        }
    
        private void sort(){
            Node<K, V>[] newNodes = new Node[len = len * 2];
            mi++;
            for (int i = 0; i < nodes.length; i++){
                if (nodes[i] != null){
                    put(newNodes, nodes[i].k, nodes[i].v);
                    Node<K, V> node = nodes[i].next;
                    while (node != null){
                        put(newNodes, node.k, node.v);
                        node = node.next;
                    }
                }
            }
            nodes = newNodes;
        }
    
        public static class Node<K, V>{
            public K k;
            public V v;
            public Node next;
            public Node(K k, V v){
                this.k = k;
                this.v = v;
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:数据结构----HashMap哈希表

        本文链接:https://www.haomeiwen.com/subject/tygjiftx.html