Data structure (Java language)-simple implementation of HashTable
The implementation of hash is usually called hash. Hash is a technique used to insert, delete, and search at the constant average time. However, Tree operations that require any sorting information between elements will not be effectively supported. The ideal hash data structure is only an array of fixed sizes containing items. Generally, search is performed on a certain part of the item (data domain), which is called a keyword. For example, an item can consist of a string (as a keyword) and other data fields. The table size is considered as a part of the hash data structure, not just a global variable. The usual habit is to make the table change from 0 to TableSize-1.
Each keyword is mapped to a number in the range from 0 to TableSize-1 and placed in an appropriate unit. This ing is called a hash function. Ideally, it should be easy to calculate and ensure that any two different keywords are mapped to different units. However, this is not possible, because the number of units is limited, and keywords are not enough. Therefore, we look for a hash function, which requires a balanced allocation of keywords between units.
This is the basic idea of hashing. The problem is that you need to select a function to determine when two keywords are hashed to the same value (that is, a conflict occurs) what should be done and how to determine the size of the hash.
If the keyword entered by the hash function is an integer, the general reasonable method is to directly return the Key mod TableSize, unless the Key happens to have some undesirable properties. In this case, the selection of hash functions needs to be carefully considered. For example, if the table size is 10 and the keywords are all 0-bit, the hash function of the above standard is not very good. To avoid the above situation, a good way is to ensure that the table size is a prime number. When the input keyword is a random integer, the hash function is not only easy to calculate, but also evenly distributes the keywords. Generally, the keyword is a string. In this case, the hash function needs to be carefully selected. The remaining major programming details are the elimination of conflicts. If an element is inserted with the same value as an inserted element, a conflict is generated. This conflict must be eliminated. There are several ways to solve this conflict. Here we mainly introduce the separated Link Method and the open addressing method. The separated Link Method separates all elements hashed to the same value and keeps them in a table. We can use the standard library table implementation method. If the space is very tight, you can avoid using them (because these tables are two-way linked and waste space ). To perform a search, we use the hash function to determine which linked list to traverse, then, we can check whether the element is in the proper position in the corresponding linked list (if repeated elements are allowed to be inserted, we usually need to set aside an additional field, this field is increased by 1 when a matching event occurs ). If this element is a new element, it will be inserted into the front-end of the linked list, not only for convenience, but also for the frequent occurrence of such a thing: newly inserted elements are most likely to be accessed soon. The following is a list of simple implementations using the separated link method:
Import java. util. iterator; import java. util. using list; import java. util. list; import java. util. random; public class SeparateChainingHashTable {private static final int DEFAULT_TABLE_SIZE = 10; // default capacity private List [] theLists; // The array private int currentSize of the hash List; // Current Data Count public SeparateChainingHashTable () {this (DEFAULT_TABLE_SIZE);} public SeparateChainingHashTable (int size) {theLists = new shard list [nextPrime (Size)]; for (int I = 0; I <theLists. length; I ++) {theLists [I] = new partition List () ;}/ *** empty the hash table */public void makeEmpty () {for (list List: theLists) {list. clear ();} currentSize = 0;}/*** whether the hash table contains an element * @ param x query element * @ return query result */public boolean contains (AnyType x) {List whichList = theLists [myhash (x)]; return whichList. contains (x);}/*** insert an element into the hash table. If an element exists, do not insert the * @ param x element */public void insert (Any Type x) {List whichList = theLists [myhash (x)]; if (! WhichList. contains (x) {whichList. add (x); if (++ currentSize> theLists. length) {rehash () ;}} else {}}/*** delete an element from the hash table, if not, do not delete the * @ param x element */public void remove (AnyType x) {List whichList = theLists [myhash (x)]; if (whichList. contains (x) {whichList. remove (x); currentSize --;} else {}}/*** hash algorithm, there are multiple implementation methods * @ param x element * @ return hash value */private int myhash (AnyType x) {int hashVal = x. hashCode (); hashVal % = theLists. length; if (hashVal <0) {hashVal + = theLists. length;} return hashVal;}/*** re-hash function, run */private void rehash () {List [] oldLists = theLists when the inserted space is insufficient; // allocate a two-fold empty table theLists = new List [nextPrime (2 * theLists. length)]; for (int j = 0; j
() ;}Currentsize = 0; for (int I = 0; I <oldLists. length; I ++) {for (AnyType item: oldLists [I]) {insert (item );}}} /*** check whether an integer is a prime number * @ param num check integer * @ return check result */private static boolean isPrime (int num) {if (num = 2 | num = 3) {return true;} if (num = 1 | num % 2 = 0) {return false ;} for (int I = 3; I * I <= num; I + = 2) {if (num % I = 0) {return false ;}} return true ;} /*** returns the prime number not less than an integer * @ pa Ram num integer * @ return next prime number (which can be equal) */private static int nextPrime (int num) {if (num = 0 | num = 1 | num = 2) {return 2;} if (num % 2 = 0) {num ++ ;} while (! IsPrime (num) {num + = 2;} return num;}/*** output hash */public void printTable () {for (int I = 0; I
HashTable = new SeparateChainingHashTable
(); For (int I = 0; I <30; I ++) {hashTable. insert (random. nextInt (30);} hashTable. printTable ();}}
Execution result :-----
0
-----
1 24
-----
25 2
-----
3
-----
4 27
-----
5
-----
6 29
-----
7
-----
8
-----
-----
10
-----
-----
-----
13
-----
-----
15
-----
-----
17
-----
18
-----
19
-----
20
-----
21
-----