拉鍊法哈希表

 拉鍊法哈希表java

 2019-07-03  13:31:32node

import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * @ClassName SeparateChainHashST
 * @Author wangyudi
 * @Date 2019/7/2 22:25
 * @Version 1.0
 * @Description 拉鍊法散列表(哈希表)
 */
public class SeparateChainHashST<Key, Value> {
    private int m;//數組大小
    private int n;//鍵值對數量
    private Chain<Key, Value>[] st;//存放鏈表的數組
    private ArrayList<Key> list; //用於迭代獲取鍵的集合

    public SeparateChainHashST() {
        this(997);
    }
    public SeparateChainHashST(int m) {
        this.m = m;
        st = (Chain<Key, Value>[]) new Chain[m]; //實例化數組
        for (int i = 0; i < m; i++) {
            st[i] = new Chain<Key, Value>(); //數組每一個元素都指向一個空鏈表
        }
        this.n = 0;
    }

    public int getSize(){
        return m;
    }

    /**
     * 爲了保證每條鏈的大小保持在2~8,調整數組的大小到size
     * 將源哈希表中全部鍵值對插入到新哈希表中;而後將新哈希表中的成員給源哈希表
     * @param size
     */
    private void resize(int size){
        SeparateChainHashST<Key, Value> keyValueSeparateChainHashST = new SeparateChainHashST<>(size);
        for(int i=0;i<m;i++){
            for(Object[] o : st[i]){
                keyValueSeparateChainHashST.put((Key)o[0],(Value)o[1]);
            }
        }
        this.m = keyValueSeparateChainHashST.m;
        this.st = keyValueSeparateChainHashST.st;
    }

    /**
     * 返回可迭代的對象
     *
     * @return
     */
    public Iterable<Key> keys() {
        list = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            for (Object[] o : st[i]) {
                list.add((Key)o[0]);
            }
        }
        return list;
    }

    /**
     * 根據鍵的hashcode,計算每一個鍵的索引值
     *
     * @param key
     * @return
     */
    private int hash(Key key) {
        return (key.hashCode() & 0x7FFFFFFF) % m;
    }

    /**
     * 向哈希表中放入一個鍵值對,若是存在相同的鍵則更新該鍵的值
     *
     * @param key
     * @param value
     */
    public void put(Key key, Value value) {
        if(n>8*m){
            resize(2*m);
        }
        int i = hash(key);//找到鍵所在的數組索引
        st[i].put(key, value);//將插入鍵值對的問題交給鏈表
        n++;
    }

    /**
     * 根據鍵,從哈希表獲取相應的值;沒有該鍵則返回null
     */
    public Value get(Key key) {
        int i = hash(key);
        return st[i].get(key);
    }

    /**
     * 從哈希表刪除鍵值對,並返回被刪除鍵的值。
     *
     * @param key
     * @return
     */
    public void delete(Key key) {
        int i = hash(key);
        if(st[i].delete(key)){
            n--;
        }
        if(n>0&&n<=2*m){
            resize(m/2);
        }
    }
}


/**
 * 鏈表類
 *
 * @param <Key>
 * @param <Value>
 */
class Chain<Key, Value> implements Iterable<Object[]> {
    private Node first;

    private class Node {
        Key key;
        Value value;
        Node next;

        public Node(Key key, Value value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }

    public Value get(Key key) {
        for (Node i = first; i != null; i = i.next) {
            if (i.key == key) {
                return i.value;
            }
        }
        return null;
    }

    public void put(Key key, Value value) {
        for (Node i = first; i != null; i = i.next) {
            if (i.key == key) {
                i.value = value;
                return; //找到相同的鍵
            }
        }
        first = new Node(key, value, first);//在頭部加入鍵值隊
    }

    /**
     * 刪除單向鏈表中的某一個結點
     *
     * @param key
     * @return
     */
    public boolean delete(Key key) {
//        if (first == null) {
//            return false;
//        }
//        if (first.key == key) {  //判斷首結點
//            first = first.next;
//            return true;
//        }
        Node f = null; //保存前一結點的信息
        Node b = first;
        while (b != null && b.key != key) {
            f = b;
            b = b.next;
        }
        if (b != null) { //找到要刪除的對象
            if(f==null){
                first=b.next; //特殊處理
            }else {
               f.next = b.next;
            }
            b.next = null;
            b = null;
            return true;
        }
        return false;
    }

    @Override
    public Iterator<Object[]> iterator() {
        return new Iterator() {
            Node i = first;

            @Override
            public boolean hasNext() {
                if (i != null) return true;
                return false;
            }

            @Override
            public Object[] next() {
                Key tempkey = i.key;
                Value tempValue = i.value;
                Object[] info = new Object[]{(Object)tempkey,(Object)tempValue};
                i = i.next;
                return info;
            }
        };
    }
//    public Iterator<Node> nodeIterator(){
//        return new Iterator<Node>() {
//            Node i = first;
//            @Override
//            public boolean hasNext() {
//                if(i!=null)return true;
//                return false;
//            }
//
//            @Override
//            public Node next() {
//                Node temp = i;
//                i = i.next;
//                return temp;
//            }
//        };
//    }
}

 

public class TestCase {
    public static void main(String[] args) {
        SeparateChainHashST<Integer, String> separateChainHashST = new SeparateChainHashST<>(100);
        separateChainHashST.put(12,"12..");
        separateChainHashST.put(2,"2..");
        separateChainHashST.put(34,"34..");
        separateChainHashST.put(17,"17..");
        separateChainHashST.put(55,"55..");
        separateChainHashST.put(214,"214..");
        separateChainHashST.put(12,"12..");
        separateChainHashST.put(2,"2..");
        separateChainHashST.put(34,"34..");
        separateChainHashST.put(17,"17..");
        separateChainHashST.put(55,"55..");
        separateChainHashST.put(214,"214..");
        for(Integer i : separateChainHashST.keys()){
            System.out.println(i);
        }

        System.out.println("===============================================");
        separateChainHashST.delete(34);
        for(Integer i : separateChainHashST.keys()){
            System.out.println(i);
        }
        System.out.println("===============================================");
        System.out.println(separateChainHashST.get(55));
        System.out.println("===============================================");
        System.out.println(separateChainHashST.getSize());
    }
}

//結果
2
12
214
214
17
34
55
===============================================
2
55
12
214
214
17
===============================================
55..
===============================================
50
相關文章
相關標籤/搜索