java hash table (hash table linear probe. chained hash table)

Hash table (hash table)

By the hash function storage position of the element between its key code and be able to establish one mapping can be found when looking at the elements quickly. 

Hash table hash table (key, value) actually very simple, the Key is converted into an integer number by a fixed algorithm function called a hash function both, then the digital array modulo length, I take it as a result of the subscript of the array, the array will be the subject of space to the value stored in digital for the next years.


1. hash collision :

It is the key (key) after the results obtained by the hash function as the address to store the current key-value pairs, but found that the address has already been a first-come, there might be conflicts. This conflict is the hash conflict.

2 . Load factoe load factor :

Total number of occupied barrel / barrel

When the load factor of expansion should be more than 0.8. 

Because of hash collisions caused by additions and deletions to check the time complexity of the hash table can only be infinitely close to 0 (1)

3. hash conflict resolution :

1. The key may be stored in the table of "Next" and "empty position. That is starting from the position of conflict, the probe back sequentially, until you find an empty position ( linear probe ). 

 2. To achieve the chain hash table , fundamentally speaking, is composed of a set list. Each list can be seen as a "bucket", we will all elements by way hash into various concrete buckets. Insert element, which is key to pass a first hash function (a process known as hash key), which elements function tells "bucket" manner by hashing belongs, and then inserted in the corresponding list head element. Locating or deleting elements, in the same way to find the elements of "buckets" and then traverse the corresponding list until you find the elements we want. Because each "bucket" is a chain, so the chain does not limit the number of hash table contains elements. However, if the table becomes too large, its performance will be reduced.

3. advantages : CRUD O (1)

   Disadvantages : 1. relatively large memory for
              2. element has no order

 

4. Source:

Linear probing hash table

class LinerHashMap <T the extends the Comparable <T >> {
     // hash table array 
    Private the Entry <T> [] hashTable;
     // number of occupied tub 
    Private  int usedBucketNum;
     // load factor of the hash table 
    Private  Double loadFactor;
     // definition of prime number table 
    Private  static  int [] primTable;
     // record the number of currently used subscript prime 
    Private  int primIndex;

    // static class initialization block 
    static {
        primTable = new  int [] {3, 7, 23, 47, 97, 127 };
    }

    /**
     * Constructor to initialize
     */
    public LinerHashMap(){
        this.primIndex = 0;
        this.hashTable = new Entry[primTable[this.primIndex]];
        this.usedBucketNum = 0;
        this.loadFactor = 0.75;
    }

    /**
     * Add elements
     * @Param Key
      * / 
    public  void PUT (T Key) {
         // compute the hash table needs expansion 
        Double RET = the this .usedBucketNum * 1.0 / the this .hashTable.length;
         IF (RET> the this .loadFactor) {
            a resize (); // hash table expansion 
        }

        // first key calculation should be placed in the tub index 
        int index = key.hashCode ()% the this .hashTable.length;
         int IDX = index;
         do {
             // representation is never used tub 
            IF ( the this .hashTable [ IDX] == null ) {
                 the this .hashTable [IDX] = new new the Entry <> (Key, State.USING);
                 the this .usedBucketNum ++ ;
                 return ;
            }

            // 表示使用过的桶
            if(this.hashTable[idx].getState() == State.USED){
                this.hashTable[idx].setData(key);
                this.hashTable[idx].setState(State.USING);
                this.usedBucketNum++;
                return;
            } The else {
                 // the tub is being used, the element is not inserted repeat 
                IF ( the this .hashTable [IDX] .getData () the compareTo (Key) == 0. {)
                     Return ;
                }
            }
            idx = (idx+1)%this.hashTable.length;
        } while(idx != index);
    }

    /**
     * Hash table expansion function
     */
    private void resize() {
        Entry<T>[] oldHashTable = this.hashTable;
        this.hashTable = new Entry[primTable[++this.primIndex]];
        this.usedBucketNum = 0;

        for (int i = 0; i < oldHashTable.length; i++) {
            if(oldHashTable[i] != null
                    && oldHashTable[i].getState() == State.USING){
                this.put(oldHashTable[i].getData());
                this.usedBucketNum++;
            }
        }
    }

    /**
     * Remove elements
     * @Param key
      * / 
    public  void Remove (T key) {
         // first key calculation should be placed in the tub index 
        int index = key.hashCode ()% the this .hashTable.length;

        // start looking element from the current position 
        int IDX = index;
         do {
             // If they traverse barrel found never used the tub, directly back 
            IF ( the this .hashTable [IDX] == null ) {
                 return ;
            }
            if(this.hashTable[idx].getState() == State.USING
                    && this.hashTable[idx].getData().compareTo(key) == 0){
                this.hashTable[idx].setData(null);
                this.hashTable[idx].setState(State.USED);
                this.usedBucketNum--;
                return;
            }
            idx = (idx+1)%this.hashTable.length;
        } while(idx != index);
    }

    /**
     * Query key element of the return value, return null not found
     * HashMap
     * @param key
     * @Return 
     * / 
    public T GET (T key) {
         // first key calculation should be placed in the tub index 
        int index = key.hashCode ()% the this .hashTable.length;

        // start looking element from the current position 
        int IDX = index;
         do {
             // during traversal of the tub if found barrel never used directly back 
            IF ( the this .hashTable [IDX] == null ) {
                 return  null ;
            }
            if(this.hashTable[idx].getState() == State.USING
                    && this.hashTable[idx].getData().compareTo(key) == 0){
                return key;
            }
            idx = (idx+1)%this.hashTable.length;
        } while(idx != index);

        return null;
    }

    /**
     * Define the value of a barrel of state
     */
    static enum State{
        UNUSE, // bucket never used 
        USED, // bucket was used the 
        the USING // bucket is in use 
    }

    /**
     * Define element types barrel
     * @param <T>
     */
    static class Entry<T extends Comparable<T>>{
        T data;
        State state;

        public Entry(T data, State state) {
            this.data = data;
            this.state = state;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public State getState() {
            return state;
        }

        public void setState(State state) {
            this.state = state;
        }
    }
}

 

Chain probe hash table

public class LinkHashTable<K extends Comparable<K>,V> {

    // Hash bucket 
    Private the Entry <K, V> [] Table;
     // load factor of 0.75 
    Private  Double loadFactor;
     // record the number of already occupied tub 
    Private  int usedBucketSize;

    /**
     * Hash table initialization
     */
    public LinkHashTable(){
        this.table = new Entry[3];
        this.loadFactor = 0.75;
        this.usedBucketSize = 0;
    }

    /**
     * Add elements to hash table
     * @param key
     * @param value
     */
    public void put(K key, V value){
        if(this.usedBucketSize*1.0/this.table.length>this.loadFactor){
            this.expand();
        }
        int idx = key.hashCode() % this.table.length;
        if(this.table[idx]==null){
            this.table[idx]=new Entry<>(key,value,null);
            this.usedBucketSize++;
            return;
        }
        The Entry <K, V> entry = the this .table [IDX];
         // determine whether the key, if there is a direct replacement for 
        the while (entry =! Null ) {
             IF (entry.key.compareTo (Key) == 0 ) {
                entry.value=value;
                return;
            }
            entry=entry.next;
        }
        this.table[idx]=new Entry<>(key,value,this.table[idx]);
    }

    /**
     * Query key exists in the hash table, if the key exists, it returns the value corresponding to the value,
     * Otherwise return null
     * @param key
     * @return
     */
    public V get(K key){
        int idx = key.hashCode() % this.table.length;
        if(this.table[idx]==null){
            return null;
        }
        Entry<K,V>entry=this.table[idx];
           while (entry!=null){
               if(entry.key.compareTo(key)==0){
                   return entry.value;
               }
               entry=entry.next;
           }
        return null;
    }

    /**
     * Remove the hash table key value parameters specified node
     * @param key
     */
    public void remove(K key){
        int index = key.hashCode() % this.table.length;
        if(this.table[index]==null){
            return;
        }else if(this.table[index].key.compareTo(key)==0){
            this.table[index]=this.table[index].next;
            return;
        }
        Entry<K,V>entry=this.table[index];
        Entry<K,V>entry1=entry.next;
        if(entry1!=null){
            if(entry1.key.compareTo(key)==0){
                entry.next=entry1.next;
            }
            entry=entry.next;
            entry1=entry1.next;
        }
        if(this.table[index]==null){
            this.usedBucketSize--;
        }
    }

    /**
     * Hash table expansion function
     */
    private void expand() {
        Entry<K, V>[] oldTable = this.table;
        this.table = new Entry[oldTable.length * 2 + 1];
        this.usedBucketSize = 0;
        for (int i = 0; i < oldTable.length; i++) {
            if (oldTable[i] != null) {
                this.put(oldTable[i].key, oldTable[i].value);
            }
        }
    }
    /**
     * Type the chain hash table node
     * @param <K,V>
     */
    static class Entry<K extends Comparable<K>,V> {
        K key;  // student id
        V value; // student
        Entry<K, V> next;

        public Entry(K key, V value, Entry<K, V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/jiezai/p/11032306.html