文章目录


添加、查找

删除

  • 惰性删除

HashEntry 引用数组的每一项是下列3钟情形之一:

  1. null。
  2. 非null。且该项是活动的(isActive 为 true)。
  3. 非null。且该标记已经被删除(isActive 为 false)。

代码

package cn.edut.algorithm;

import java.util.Currency;

import com.sun.webkit.ContextMenu.ShowContext;

public class QuadraticProbingHashTable<K,V> {
	public QuadraticProbingHashTable() {
		this(DEFAULT_TABLE_SIZE) ;
	}
	
	
	
	public QuadraticProbingHashTable(int tableSize) {
		allocateTable(tableSize);
		makeEmpty();
	}



	public void makeEmpty() {
		size = 0 ; 
		for (int i = 0; i < table.length; i++) {
			table[i] = null; 
		}
	}

	public boolean containsKey(K key ) {
		int index = findIndex(key);
		return isActive(index); 
	}
	
	public void put(K key , V value ) {
		
		if(size>=table.length/2) {
			rehash((int) nextPrime(table.length*2));
		}
		
		int index = findIndex(key);
		table[index] = new HashEntry<K, V>(hash(key), key, value, true) ;
		size++ ; 
	}
	private void rehash(int newSize) {
		HashEntry<K, V>[] oldTable = table;
		
		allocateTable(newSize);
		size=0 ; 
		
		for (int i = 0; i < oldTable.length; i++) {
			HashEntry<K, V> e = oldTable[i];
			if(e!=null) {
				put(e.key,e.value);
			}
		}
	}



	public int findIndex(K key ) {
		int hash = hash(key);
		int index = indexFor(hash);
		int offset = 1 ;
		while(isActive(index)) {
			if(table[index].key.equals(key)) {
				return index ; 
			}
			index += offset ;
			offset += 2; // 
			if(index>=table.length) {
				index-=table.length;
			}
		}
		return index ; 
		
	}
	public void remove(K key) {
		int index = findIndex(key);
		table[index].isActive = false;
	}

	public void showTable() {
		System.out.print("[");
		for (int i = 0; i < table.length; i++) {
			HashEntry<K, V> t = table[i] ;
			if(isActive(i)) {
				System.out.print(" "+t.key +":"+t.value+" ");
			}else {
				System.out.print( " ---- " );
			}
		}
		System.out.println("]");
	}


	public int size() {
		return size ; 
	}
	
	
	private static final int DEFAULT_TABLE_SIZE = 11 ; //必须要是素数
	private HashEntry<K, V>[] table  ; //The array of elements ;
	private int size ; //当前数据量
	
	
	/** * 节点 */
	private static class HashEntry<K,V> {
		private int hash ; 
		private K key ; 
		private V value ; 
		private boolean isActive =false ;
		public HashEntry(int hash, K key, V value, boolean isActive) {
			super();
			this.hash = hash;
			this.key = key;
			this.value = value;
			this.isActive = isActive;
		}
	}
	
	public int indexFor(int hash ) {
		return hash % table.length ; 
	}
	
	public int hash(K key) {
		int h = key.hashCode();
		return h^(h>>>4)^(h>>>7)^(h>>>12)^(h>>>20);
	}
	
	public long nextPrime(long  n) {
		if(n<2) return 2; 
		while(!isPrime(++n)) {
			
		}
		return n;
	}
	
	/** * 方法2 : 位运算,快一点点 */
	public boolean isPrime(long n) {
		if(n<2) {
			return false; 
		}else if(n>2) {
			if(((n^0)&1) == 0) {  //偶数
				return false; 
			}
			long len = (long) Math.sqrt(n);
			for (int i = 3; i <= len; i++) {
				if(n%i==0 ) {
					return false; 
				}
			}
		}
		return true; 
	}
	
	@SuppressWarnings("unchecked")
	private void allocateTable(int tableSize) {
		table = new HashEntry[tableSize] ; 
	}
	
	private void rehash() {
		//TODO 
	}
	
	private boolean isActive(int index) {
		return  table[index]!=null && table[index].isActive;
	}



	public static void main(String[] args) {
		QuadraticProbingHashTable<Integer, Integer> map= new QuadraticProbingHashTable<>();
		for (int i = 0; i < 100; i++) {
			System.out.println(i+" : "+map.isPrime(i) + " : "+ map.nextPrime(i));
		}
		int key = 10101;
		int hash  = map.hash(key);
		int index = map.indexFor(hash); 
		System.out.println("key:"+key + ", hash:"+ hash + ", index:"+index);
		
		/* * show */
		map.showTable();
		
		map.put(key, 33 );
		map.put(key, 66 );
		map.put(key-11, 44 );
		map.put(key-12, 55 );
		
		map.showTable();
		
		System.out.println(map.containsKey(key));
		map.remove(key);
		System.out.println(map.containsKey(key));
		map.showTable();
		
		
		System.out.println("---------------");
		for (int i = 0; i < 10; i++) {
			map.put(key+i, i);
			map.showTable();
		}
	}
	
}




测试结果

0 : false : 2
1 : false : 2
2 : true : 3
3 : true : 5
4 : false : 5
5 : true : 7
6 : false : 7
7 : true : 11
8 : false : 11
9 : false : 11
10 : false : 11
11 : true : 13
12 : false : 13
13 : true : 17
14 : false : 17
15 : false : 17
16 : false : 17
17 : true : 19
18 : false : 19
19 : true : 23
20 : false : 23
21 : false : 23
22 : false : 23
23 : true : 29
24 : false : 29
25 : false : 29
26 : false : 29
27 : false : 29
28 : false : 29
29 : true : 31
30 : false : 31
31 : true : 37
32 : false : 37
33 : false : 37
34 : false : 37
35 : false : 37
36 : false : 37
37 : true : 41
38 : false : 41
39 : false : 41
40 : false : 41
41 : true : 43
42 : false : 43
43 : true : 47
44 : false : 47
45 : false : 47
46 : false : 47
47 : true : 53
48 : false : 53
49 : false : 53
50 : false : 53
51 : false : 53
52 : false : 53
53 : true : 59
54 : false : 59
55 : false : 59
56 : false : 59
57 : false : 59
58 : false : 59
59 : true : 61
60 : false : 61
61 : true : 67
62 : false : 67
63 : false : 67
64 : false : 67
65 : false : 67
66 : false : 67
67 : true : 71
68 : false : 71
69 : false : 71
70 : false : 71
71 : true : 73
72 : false : 73
73 : true : 79
74 : false : 79
75 : false : 79
76 : false : 79
77 : false : 79
78 : false : 79
79 : true : 83
80 : false : 83
81 : false : 83
82 : false : 83
83 : true : 89
84 : false : 89
85 : false : 89
86 : false : 89
87 : false : 89
88 : false : 89
89 : true : 97
90 : false : 97
91 : false : 97
92 : false : 97
93 : false : 97
94 : false : 97
95 : false : 97
96 : false : 97
97 : true : 101
98 : false : 101
99 : false : 101
key:10101, hash:9550, index:2
[ ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ]
[ ---- ---- 10101:66 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ]
true
false
[ ---- ---- ---- ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ]
《---------------
[ ---- ---- 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ]
[ ---- ---- ---- ---- 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- ---- ---- 10104:3 ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- ---- 10105:4 10104:3 ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- 10106:5 10105:4 10104:3 ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- 10107:6 10106:5 10105:4 10104:3 ---- ---- ---- ---- ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- 10107:6 10106:5 10105:4 10104:3 ---- ---- ---- 10108:7 ---- ]
[ ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- 10107:6 10106:5 10105:4 10104:3 ---- ---- 10109:8 10108:7 ---- ]
[ 10110:9 10109:8 10108:7 ---- ---- ---- ---- 10103:2 10102:1 10101:0 ---- 10090:44 ---- ---- 10089:55 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 10107:6 10106:5 10105:4 10104:3 ---- ]