自己实现一个简单的散列表

来源:互联网 发布:代理商查询系统源码 编辑:程序博客网 时间:2024/06/07 15:33

需求

自己实现一个简单的散列表,使用平方探测(quadratic probing).

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

代码

import java.util.StringJoiner;public class QuadraticProbingHashTable<T> {    public QuadraticProbingHashTable() {        this(DEFAULT_TABLE_SIZE);    }    public QuadraticProbingHashTable(int size) {        allocateArray(size);        makeEmpty();    }    private void makeEmpty() {        currentSize = 0;        for (int i = 0; i < array.length; i++) {            array[i] = null;        }    }    public int size() {        return currentSize;    }    public boolean isEmpty() {        return currentSize == 0;    }    public boolean contains(T t) {        int currentPos = findPos(t);        return isActive(currentPos);    }    public void insert(T t) {        int currentPos = findPos(t);        if (isActive(currentPos))            return;        array[currentPos] = new HashEntry<T>(t);        currentSize++;        if (currentSize > array.length / 2)            rehash();    }    private void rehash() {        HashEntry<T>[] oldArray = array;        allocateArray(nextPrime(oldArray.length * 2));        currentSize = 0;        for (int i = 0; i < oldArray.length; i++) {            if (oldArray[i] != null && oldArray[i].isActive) {                insert(oldArray[i].element);            }        }    }    public void remove(T t) {        int currentPos = findPos(t);        if (isActive(currentPos)){                array[currentPos].isActive = false;                currentSize--;            }    }    @Override    public String toString() {        StringJoiner joiner = new StringJoiner(", ", "[", "]");        for (int i = 0; i < array.length; i++) {            if (array[i] != null && array[i].isActive) {                joiner.add(array[i].element.toString());            }        }        return joiner.toString();    }    private static class HashEntry<T> {        T element;        boolean isActive;        public HashEntry(T element) {            this(element, true);        }        public HashEntry(T element, boolean isActive) {            this.element = element;            this.isActive = isActive;        }    }    private static final int DEFAULT_TABLE_SIZE = 11;    private HashEntry<T>[] array;    private int currentSize;    @SuppressWarnings("unchecked")    private void allocateArray(int size) {        array = new HashEntry[nextPrime(size)];    }    private boolean isActive(int currentPose) {        return array[currentPose] != null && array[currentPose].isActive;    }    private int findPos(T t) {        int offset = 1;        int currentPos = myhash(t);        while (array[currentPos] != null && !array[currentPos].element.equals(t)) {            currentPos += offset;            offset += 2;            if (currentPos >= array.length)                currentPos -= array.length;        }        return currentPos;    }    private int myhash(T t) {        int hashVal = t.hashCode();        hashVal %= array.length;        if (hashVal < 0)            hashVal += array.length;        return hashVal;    }    private static int nextPrime(int n) {        if (n % 2 == 0)            n++;        while (!isPrime(n))            n += 2;        return n;    }    private static boolean isPrime(int n) {        if (n == 2 || n == 3)            return true;        if (n == 1 || n % 2 == 0)            return false;        for (int i = 3; i * i <= n; i += 2)            if (n % i == 0)                return false;        return true;    }}
原创粉丝点击