数据结构学习笔记之哈希表

                                                                    数据结构-哈希表 学习笔记

 

 

 

 

散列表(又称散列映射,字典,关联数组)是一种用于以常数平均时间执行插入,删除,查找的技术。

应用:常用于查找;做缓存。
 

 

 

 

Java代码实现:


/**
 * 非线性存储结构: 哈希表
 * 
 * @see java.util.Hashtable
 * @see java.util.HashMap
 * 
 */
public class HashTable {

	/** 默认容量 */
	private static final int DEFAULT_CAPACITY = 1 << 4;

	/** 最大容量 */
	private static final int MAX_CAPACITY = 1 << 16;

	/** 负载因子 */
	private static final double DEFAULT_LOAD_FACTOR = 0.75;

	/** 内部链表数组 */
	private Node[] table;

	/** 负载因子 */
	private final double loadFactor;

	/** 触发表重算的阈值(threshold = capacity * loadfactor) */
	private int threshold;

	/** 哈希表的大小 */
	private int size = 0;

	/** 构造 */
	@SuppressWarnings("unchecked")
	public HashTable(int initialCapacity, double loadFactor) {
		if (initialCapacity < 0)
			throw new IllegalArgumentException("Illegal initial capacity:" + initialCapacity);
		if (initialCapacity > MAX_CAPACITY)
			initialCapacity = MAX_CAPACITY;
		if (loadFactor <= 0 || Double.isNaN(loadFactor))
			throw new IllegalArgumentException("Illegal load factor:" + loadFactor);
		int capacity = 1;
		while (capacity < initialCapacity)
			capacity <<= 1;

		this.loadFactor = loadFactor;
		threshold = (int) (capacity * loadFactor);
		table = new Node[threshold]; //
	}

	/** 构造 */
	public HashTable(int initialCapacity) {
		this(initialCapacity, DEFAULT_LOAD_FACTOR);
	}

	/** 构造 */
	@SuppressWarnings("unchecked")
	public HashTable() {
		this.loadFactor = DEFAULT_LOAD_FACTOR;
		threshold = (int) (DEFAULT_CAPACITY * DEFAULT_LOAD_FACTOR);
		table = new Node[DEFAULT_CAPACITY]; //
	}

	/** 添加数据 */
	public boolean add(E e) {
		int pos = hash(e) % table.length;
		Node b = table[pos];
		if (b == null) {
			table[pos] = new Node<>(hash(e), e, null);
		} else {
			while (b.next != null)
				b = b.next;
			b.next = new Node<>(hash(e), e, null);
		}
		if (size++ >= threshold) //
			resize(table.length * 2);
		return true;
	}

	/** 删除数据 */
	public boolean remove(Object o) {
		int h = hash(o) % table.length;
		Node b = table[h];
		if (b == null)
			return false;
		if (b.value.equals(o)) {
			if (b.next == null) {
				table[h] = null;
			} else {
				table[h] = b.next;
			}
			size--;
			return true;
		} else {
			while (b.next != null) {
				Node c = b;
				b = b.next;
				if (b.value.equals(o)) {
					c.next = b.next;
					size--;
					return true;
				}
			}
		}
		return false;
	}

	/** 查找数据 */
	public boolean contains(Object e) {
		int p = hash(e) % table.length;
		Node o = table[p];
		if (o == null)
			return false;
		if (!o.value.equals(e)) {
			while (o.next != null) {
				o = o.next;
				if (o.value.equals(e))
					return true;
			}
		} else {
			return true;
		}
		return false;
	}

	/** 重算内部链表数组的大小,完成扩容 */
	@SuppressWarnings("unchecked")
	void resize(int newCapacity) {
		Node[] old = table;
		int oldCapacity = old.length;
		if (oldCapacity == MAX_CAPACITY) {
			threshold = MAX_CAPACITY;
			return;
		}
		threshold = (int) (newCapacity * loadFactor);
		Node[] newTable = new Node[newCapacity];
		transfer(newTable);
		table = newTable;
	}

	/** 将扩容前表的数据 复制到新表中 */
	void transfer(Node[] newTable) {
		Node[] src = table;
		int newCapacity = newTable.length;
		for (int n = 0; n < src.length; n++) {
			Node e = src[n];
			if (e != null) {
				src[n] = null;
				do {
					Node next = e.next;
					int i = e.hash % newCapacity; // 扩容后获得数据在哈希表中新的存储位置
					e.next = newTable[i];
					newTable[i] = e;
					e = next;
				} while (e != null);
			}
		}
	}

	/* 链表实现 */
	static final class Node {

		final int hash; // 哈希值
		final E value; // 数据
		Node next; // 上一个节点

		Node(int hash, E value, Node next) {
			this.hash = hash;
			this.next = next;
			this.value = value;
		}

		@Override
		public int hashCode() {
			return Objects.hashCode(value);
		}

		@Override
		public boolean equals(Object o) {
			if (o == this)
				return true;
			if (o instanceof Node) {
				Node b = (Node) o;
				if (Objects.equals(value, b.value))
					return true;
			}
			return false;
		}

		public String toString() {
			return value.toString();
		}

	}

	/** 迭代器 */
	class HashIterator implements Iterator> {
		Node next; // 下一个
		int index; // 位置
		Node current; // 当前节点

		HashIterator() {
			if (size > 0) {
				Node[] t = (Node[]) table;
				while (index < t.length && (next = t[index++]) == null)
					;
			}
		}

		@Override
		public boolean hasNext() {
			return next != null;
		}

		@Override
		public Node next() {
			Node e = next;
			if (e == null)
				throw new NoSuchElementException();

			if ((next = e.next) == null) {
				Node[] t = (Node[]) table;
				while (index < t.length && (next = t[index++]) == null)
					;
			}
			current = e;
			return e;
		}

	}

	/** 获得迭代器 */
	public Iterator> iterator() {
		return new HashIterator();
	}

	/**  */
	static final class HashSpliterator implements Spliterator {

		HashSpliterator() {
			
		}

		@Override
		public boolean tryAdvance(Consumer action) {

			return false;
		}

		@Override
		public Spliterator trySplit() {

			return null;
		}

		@Override
		public long estimateSize() {

			return 0;
		}

		@Override
		public int characteristics() {

			return 0;
		}

	}

	@Override
	public int hashCode() {
		int h = 0;
		Iterator> i = iterator();
		while (i.hasNext())
			h += Objects.hashCode(i.next().value);
		return h;
	}

	@Override
	public boolean equals(Object o) {
		if (o == this)
			return true;
		if (!(o instanceof HashTable))
			return false;
		HashTable t = (HashTable) o;
		if (t.size() != size())
			return false;
		Iterator i = t.iterator();
		while (i.hasNext()) {
			Node n = (Node) i.next();
			if (!contains(n.value))
				return false;
		}
		return true;
	}

	/** 哈希函数:确定数据在HashTable数组中的位置 */
	public static final int hash(Object o) {
		return o == null ? 0 : Objects.hashCode(o);
	}
	
	/** 返回哈希表的大小 */
	public int size() {
		return size;
	}

	/** 字符串输出 */
	public String toString() {
		StringBuilder s = new StringBuilder();
		s.append('{');
		for (int a = 0; a < table.length; a++) {
			if (table[a] != null) {
				s.append(table[a].value).append(',');
				Node e = table[a].next;
				while (e != null) {
					s.append(e.value).append(',');
					e = e.next;
				}
			}
		}
		int len = s.length();
		if (s.lastIndexOf(",") == len - 1)
			s.deleteCharAt(len - 1);

		return s.append('}').toString();

		// Iterator i = iterator();
		// if (!i.hasNext())
		// return "{}";
		// StringBuilder s = new StringBuilder();
		// s.append('{');
		// for (;;) {
		// s.append(i.next());
		// if (!i.hasNext())
		// return s.append('}').toString();
		//
		// s.append(',').append(' ');
		// }
	}

}

 

注:

 

你可能感兴趣的:(Data)