The following is a detailed analysis of the Code implemented by the hash table experiment in C language. For more information, seeCopy codeThe Code is as follows:
/*
Data Structure hash table in C Language
*/
# Include <stdio. h>
# Include <malloc. h>
# Define NULLKEY 0 // 0 indicates no record mark
# Define N 10 // number of data elements
Typedef int KeyType; // set the keyword field to an integer.
Typedef struct
{
KeyType key;
Int ord;
} ElemType; // data element type
// Open the storage structure of the address hash table
Int hashsize [] = {11,19, 29,37}; // hash table Capacity Increment table, a proper Prime Number Sequence
Int m = 0; // hash table length, global variable
Typedef struct
{
ElemType * elem; // The base address for storing data elements and dynamically allocating Arrays
Int count; // number of current data elements
Int sizeindex; // hashsize [sizeindex] indicates the current capacity.
} HashTable;
# Define SUCCESS 1
# Define UNSUCCESS 0
# Define DUPLICATE-1
// Construct an empty hash table
Int InitHashTable (HashTable * H)
{
Int I;
(* H). count = 0; // The number of current elements is 0
(* H). sizeindex = 0; // The initial storage capacity is hashsize [0]
M = hashsize [0];
(* H). elem = (ElemType *) malloc (m * sizeof (ElemType ));
If (! (* H). elem)
Exit (0); // storage allocation failed
For (I = 0; I <m; I ++)
(* H). elem [I]. key = NULLKEY; // flag of the record not filled
Return 1;
}
// Destroy Hash Table H
Void DestroyHashTable (HashTable * H)
{
Free (* H). elem );
(* H). elem = NULL;
(* H). count = 0;
(* H). sizeindex = 0;
}
// A simple hash function (m is the table length and global variable)
Unsigned Hash (KeyType K)
{
Return K % m;
}
// Open addressing method for conflict handling
Void collision (int * p, int d) // returns the hash value after linear detection.
{
* P = (* p + d) % m;
}
// Algorithm 9.17
// Search for elements whose key code is K in the open address Hash Table H. if the search is successful, use p to indicate the data to be queried.
// Position the element in the table and return SUCCESS; otherwise, use p to indicate the insertion position and return UNSUCCESS
// C is used to calculate the number of conflicts. The initial value is set to zero for reference during table creation and insertion.
Int SearchHash (HashTable H, KeyType K, int * p, int * c)
{
* P = Hash (K); // obtain the Hash address.
While (H. elem [* p]. key! = NULLKEY &&! (K = H. elem [* p]. key ))
{
// Records are entered in this position, and the keywords are not equal.
(* C) ++;
If (* c <m)
Collision (p, * c); // obtain the next probe address p
Else
Break;
}
If (K = H. elem [* p]. key)
Return SUCCESS; // if the search is successful, p returns the position of the data element to be queried.
Else
Return UNSUCCESS; // the query fails (H. elem [p]. key = NULLKEY), and p returns the insert position.
}
Int InsertHash (HashTable *, ElemType); // declares a function.
// Rebuild the hash table
Void RecreateHashTable (HashTable * H) // rebuild the hash table
{
Int I, count = (* H). count;
ElemType * p, * elem = (ElemType *) malloc (count * sizeof (ElemType ));
P = elem;
Printf ("Rebuilding hash table n ");
For (I = 0; I <m; I ++) // Save the original data to elem
If (* H). elem + I)-> key! = NULLKEY) // The Unit has data
* P ++ = * (* H). elem + I );
(* H). count = 0;
(* H). sizeindex ++; // increase the storage capacity
M = hashsize [(* H). sizeindex];
P = (ElemType *) realloc (* H). elem, m * sizeof (ElemType ));
If (! P)
Exit (0); // storage allocation failed
(* H). elem = p;
For (I = 0; I <m; I ++)
(* H). elem [I]. key = NULLKEY; // flag of records not filled (initialization)
For (p = elem; p <elem + count; p ++) // Insert the original data into the rebuilt hash table based on the new table length.
InsertHash (H, * p );
}
// Algorithm 9.18
// When the search fails, insert the Data Element e to the open Hash Table H and return 1;
// If the number of conflicts is too large, the hash table is rebuilt.
Int InsertHash (HashTable * H, ElemType e)
{
Int c, p;
C = 0;
If (SearchHash (* H, e. key, & p, & c) // The element with the same keyword as e already exists in the table.
Return DUPLICATE;
Else if (c {
// Insert e
(* H). elem [p] = e;
++ (* H). count;
Return 1;
}
Else
RecreateHashTable (H); // recreate the hash table
Return 0;
}
// Traverse the hash table in the order of hash addresses
Void TraverseHash (HashTable H, void (* Vi) (int, ElemType ))
{
Int I;
Printf ("hash address 0 ~ % Dn "m-1 );
For (I = 0; I <m; I ++)
If (H. elem [I]. key! = NULLKEY) // has data
Vi (I, H. elem [I]);
}
// Search for elements whose key code is K in the open address Hash Table H. if the search is successful, use p to indicate the data to be queried.
// Position the element in the table and return SUCCESS; otherwise, return UNSUCCESS
Int Find (HashTable H, KeyType K, int * p)
{
Int c = 0;
* P = Hash (K); // obtain the Hash address.
While (H. elem [* p]. key! = NULLKEY &&! (K = H. elem [* p]. key ))
{// This location contains records. The keywords are not equal.
C ++;
If (c <m)
Collision (p, c); // obtain the next probe address p
Else
Return UNSUCCESS; // search failed (H. elem [p]. key = NULLKEY)
}
If (K = H. elem [* p]. key)
Return SUCCESS; // if the search is successful, p returns the position of the data element to be queried.
Else
Return UNSUCCESS; // search failed (H. elem [p]. key = NULLKEY)
}
Void print (int p, ElemType r)
{
Printf ("address = % d (% d, % d) n", p, r. key, r. ord );
}
Int main ()
{
ElemType r [N] = {
},
}
};
HashTable h;
Int I, j, p;
KeyType k;
InitHashTable (& h );
For (I = 0; I <N-1; I ++)
{
// Insert the previous N-1 records
J = InsertHash (& h, r [I]);
If (j = DUPLICATE)
Printf ("the record with the keyword % d already exists in the table, and the record (% d, % d) n cannot be inserted ",
R [I]. key, r [I]. key, r [I]. ord );
}
Printf ("traverse the hash table in the order of hash addresses: n ");
TraverseHash (h, print );
Printf ("Enter the keyword of the record to be searched :");
Scanf ("% d", & k );
J = Find (h, k, & p );
If (j = SUCCESS)
Print (p, h. elem [p]);
Else
Printf ("n not found ");
J = InsertHash (& h, r [I]); // Insert the nth record
If (j = 0) // recreate the hash table
J = InsertHash (& h, r [I]); // re-insert the nth record after recreating the hash table
Printf ("traverse the reconstructed hash table in the order of hash addresses: n ");
TraverseHash (h, print );
Printf ("Enter the keyword of the record to be searched :");
Scanf ("% d", & k );
J = Find (h, k, & p );
If (j = SUCCESS)
Print (p, h. elem [p]);
Else
Printf ("n not found ");
DestroyHashTable (& h );
System ("pause ");
Return 0;
}
/*
Output result:
Records with a keyword of 60 in the table cannot be inserted)
Traverse the hash table in the order of hash addresses:
Hash address 0 ~ 10
Address = 1 (1, 5)
Address = 2 (2, 6)
Address = 3 (3, 7)
Address = 4 (4, 8)
Address = 5 (60, 2)
Address = 6 (17,1)
Address = 7 (29,3)
Address = 8 (38,4)
Enter the keyword of the record to be searched: 17
Address = 6 (17,1)
Rebuilding a hash table
Traverse the reconstructed hash table in the order of hash addresses:
Hash address 0 ~ 18
Address = 0 (38,4)
Address = 1 (1, 5)
Address = 2 (2, 6)
Address = 3 (3, 7)
Address = 4 (4, 8)
Address = 6 (60, 2)
Address = 10 (29,3)
Address = 13 (13, 10)
Address = 17 (17,1)
Enter the keyword of the record to be searched: 13
Address = 13 (13, 10)
Press any key to continue...
*/