一、简述
散列是一种数据访问技术,所有的数据项均有散列码与之关联。
散列码可在任何时候通过散列函数计算得到,通常为数据索引。
二、散列构造
①直接定址法:取关键字本身或其线性函数计算结果作为散列码。
②数字分析法:取关键字中分布较均匀的若干位作为散列码。
③折叠法:根据表长取关键字拆分为若干等长部分后叠加求和并去掉进位的结果作为散列码。(可存在一个不等长部分)
④平方取中法:根据表长取关键字平方数值中间的若干位作为散列码。
⑤除留余数法:根据表长取关键字模运算结果作为散列码。
三、冲突处理
①开放定址法:冲突发生后从冲突为止进行线性检索,直到检索到空的位置插入或搜索项。
②再散列法:冲突发生后使用不同的散列函数生成散列码,直到没有冲突为止。
③链地址法:每个散列码对应一个链表,直接对相应的链表进行查改即可。
④公共溢出区法:将散列表分为基本表和溢出表,将所有发生冲突的数据存入溢出表。
四、实现
①开放定址法
public class HashSet { private static final int MAX = 1000; private int[] data; private int modulo(int val) { return val % MAX; } public HashSet() { data = new int[MAX]; for (int i = 0; i < MAX; i++) data[i] = Integer.MIN_VALUE; } public boolean add(int val) { int i = modulo(val); while (i < data.length && data[i] != Integer.MIN_VALUE) { if (data[i] == val) return false; else i++; } if (i < data.length) { data[i] = val; return true; } else return false; } public boolean remove(int val) { int i = modulo(val); while (i < data.length && data[i] != val) i++; if (i < data.length) { data[i] = Integer.MIN_VALUE; return true; } else return false; } public boolean contains(int val) { int i = modulo(val); while (i < data.length && data[i] != val) i++; return i < data.length; } }
②链地址法
public class HashSet { private class Node { int val; Node next; Node(int x) { val = x; next = null; } } private static final int MAX = 10000; private Node[] heads; private int modulo(int val) { return val % MAX; } public HashSet() { heads = new Node[MAX]; for (int i = 0; i < MAX; i++) heads[i] = new Node(Integer.MIN_VALUE); } public boolean add(int val) { int i = modulo(val); Node x = heads[i]; while (x.next != null) { if (x.next.val == val) return false; x = x.next; } x.next = new Node(val); return true; } public boolean contains(int val) { int i = modulo(val); for (Node x = heads[i]; x.next != null; x = x.next) if (x.next.val == val) return true; return false; } public boolean remove(int val) { int i = modulo(val); for (Node x = heads[i]; x.next != null; x = x.next) if (x.next.val == val) { x.next = x.next.next; return true; } return false; } }