拉链法:把所有的同义词存储在一个线性链表中,这个线性链表由其散列地址唯一标识。适用于经常进行插入和删除操作的情况。
代码及注释:
1 #include"iostream" 2 #include"vector" 3 #include<time.h> 4 using namespace std; 5 6 //拉链法 7 8 struct ListNode //结点组成的是一个单链表,哈希表是一组指针,数组下标对应求出来的key值 9 { 10 int val; 11 struct ListNode* next; 12 ListNode(int x) :val(x), next(NULL){} 13 }; 14 15 int hash_func(int key, int table_len) { //求key值的方法就是,对哈希数组的长度取余 16 return key % table_len; 17 } 18 19 void insert(ListNode* hash_table[], ListNode* node, int table_len) { //插入方法是头插法 20 int hash_key = hash_func(node->val, table_len); 21 node->next = hash_table[hash_key]; 22 hash_table[hash_key] = node; 23 } 24 25 bool search(ListNode* hash_table[], int val, int table_len) { //查找的方法与插入的思想是几乎一样的 26 int hash_key = hash_func(val, table_len); //只不过插入的是结点,而查找只需要找值 27 ListNode* head = hash_table[hash_key]; 28 while (head) { 29 if (head->val == val) 30 { 31 return true; 32 } 33 head = head->next; 34 } 35 return false; 36 } 37 38 //测试: 39 int main() { 40 const int TABLE_LEN = 11; //取为质数,冲突会比较少 41 ListNode* hash_table[TABLE_LEN] = { 0 }; //指针数组 42 vector<ListNode*> hash_node_vec; 43 int test[8] = { 0 }; 44 srand(time(NULL)); //随机产生8个小于10的数 45 for (int i = 0; i < 8; i++) { 46 test[i] = rand() % 10; 47 } 48 for (int i = 0; i < 8; i++) { 49 hash_node_vec.push_back(new ListNode(test[i])); 50 } 51 for (int i = 0; i < hash_node_vec.size(); i++) { 52 insert(hash_table, hash_node_vec[i], TABLE_LEN); 53 } 54 printf("Hash table:\n"); 55 for (int i = 0; i < TABLE_LEN; i++) { 56 printf("[%d]:", i); 57 ListNode* head = hash_table[i]; 58 while (head) { 59 printf("->%d", head->val); 60 head = head->next; 61 } 62 printf("\n"); 63 } 64 printf("\n"); 65 printf("Test search:\n"); 66 for (int i = 0; i < 10; i++) { 67 if (search(hash_table, i, TABLE_LEN)) { 68 printf("%d is in the hash table.\n", i); 69 } 70 else { 71 printf("%d is not in the hash table.\n", i); 72 } 73 } 74 system("pause"); 75 return 0; 76 }
一步步朝前走,总会有收获的,keep quiet. 2020-03-20