forked from xuos/xiuos
				
			2023_open_source_contest_warmup_1st_issue1 from 上海大学_每天学习战队_姚文莹
it is OK
This commit is contained in:
		
						commit
						4b85ab3058
					
				| 
						 | 
					@ -240,6 +240,10 @@ menu "test app"
 | 
				
			||||||
                bool "Config test soft timer"
 | 
					                bool "Config test soft timer"
 | 
				
			||||||
                default n
 | 
					                default n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            menuconfig USER_TEST_HASH
 | 
				
			||||||
 | 
					                bool "Config test hash"
 | 
				
			||||||
 | 
					                default n
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            menuconfig USER_TEST_RADIX
 | 
					            menuconfig USER_TEST_RADIX
 | 
				
			||||||
                bool "Config test radix tree"
 | 
					                bool "Config test radix tree"
 | 
				
			||||||
                default n
 | 
					                default n
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,5 +105,9 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
 | 
				
			||||||
        SRC_FILES += test_radix_tree/test_radix_tree.c
 | 
					        SRC_FILES += test_radix_tree/test_radix_tree.c
 | 
				
			||||||
    endif    
 | 
					    endif    
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    ifeq ($(CONFIG_USER_TEST_HASH),y)
 | 
				
			||||||
 | 
					        SRC_FILES += test_hash/test_hash.c
 | 
				
			||||||
 | 
					    endif  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    include $(KERNEL_ROOT)/compiler.mk
 | 
					    include $(KERNEL_ROOT)/compiler.mk
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 75 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 102 KiB  | 
| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					# 基于cortex-m3-emulator实现哈希表并测试验证##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 1. 简介
 | 
				
			||||||
 | 
					利用c语言实现了哈希表(HashMap),包括添加键值对(Put),获取键对应的值(Get), 删除健(Delete),清空哈希表(Clear), 迭代遍历哈希表(hashMapIterator)等功能
 | 
				
			||||||
 | 
					操作。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					利用数组(Entry)作为存储空间,利用链表(*next)解决冲突。当哈希表的大小超过数组大小后,为避免发生冲突过多的情况,可以对哈希表扩容。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2. 数据结构设计说明
 | 
				
			||||||
 | 
					键值对结构
 | 
				
			||||||
 | 
					typedef struct entry {
 | 
				
			||||||
 | 
					    void * key;             // 键
 | 
				
			||||||
 | 
					    void * value;           // 值
 | 
				
			||||||
 | 
					    struct entry * next;    // 冲突链表
 | 
				
			||||||
 | 
					}*Entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					哈希结构
 | 
				
			||||||
 | 
					typedef struct hashMap {
 | 
				
			||||||
 | 
					    int size;           // 当前大小
 | 
				
			||||||
 | 
					    int listSize;       // 有效空间大小
 | 
				
			||||||
 | 
					    HashCode hashCode;  // 哈希函数
 | 
				
			||||||
 | 
					    Equal equal;        // 判等函数
 | 
				
			||||||
 | 
					    Entry list;         // 存储区域
 | 
				
			||||||
 | 
					    Put put;            // 添加键的函数
 | 
				
			||||||
 | 
					    Get get;            // 获取键对应值的函数
 | 
				
			||||||
 | 
					    Remove remove;      // 删除键
 | 
				
			||||||
 | 
					    Clear clear;        // 清空Map
 | 
				
			||||||
 | 
					    Exists exists;      // 判断键是否存在
 | 
				
			||||||
 | 
					    Boolean autoAssign;	// 设定是否根据当前数据量动态调整内存大小,默认开启
 | 
				
			||||||
 | 
					}*HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					包括以下函数功能,分别为:
 | 
				
			||||||
 | 
					`createHashMap`:创建一个哈希结构
 | 
				
			||||||
 | 
					`defaultPut`:添加键值对
 | 
				
			||||||
 | 
					`defaultGet`:获取键对应值
 | 
				
			||||||
 | 
					`defaultRemove`:删除指定键的键值对
 | 
				
			||||||
 | 
					`defaultExists`:判断键值是否存在
 | 
				
			||||||
 | 
					`defaultClear`:清空Map的函数类型
 | 
				
			||||||
 | 
					`resetHashMap`:重新构建哈希表
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 3. 测试程序说明
 | 
				
			||||||
 | 
					测试了哈希表的插入键值对(Put),判断键是否存在(Exist),获取键对应的值(Get), 删除健(Delete),迭代遍历哈希表(hashMapIterator),清空哈希表(Clear)等操作。
 | 
				
			||||||
 | 
					并展示了利用链地址法解决哈希冲突的示例, 两个不同的人(Bob和Li Ming)的hashcode相同。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 4. 运行结果(##需结合运行测试截图按步骤说明##)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					打开menuconfig之后,将test_hash_map开启(y),保存后退出
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					编译XiZi-cortex-m3-emulator.elf成功
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					启动qemu模拟Xiuos操作系统,验证TestHash注册Shell命令
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					执行TestHash命令,打印测试结果。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 94 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 95 KiB  | 
| 
						 | 
					@ -0,0 +1,323 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* @file:    test_hash.c
 | 
				
			||||||
 | 
					* @brief:   a application of test hash function
 | 
				
			||||||
 | 
					* @version: 3.0
 | 
				
			||||||
 | 
					* @author:  Yao wenying
 | 
				
			||||||
 | 
					* @date:    2023/05/26
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <transform.h>
 | 
				
			||||||
 | 
					#include"test_hash.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int defaultHashCode(HashMap hashMap, let key) {
 | 
				
			||||||
 | 
						char * k = (char *)key;
 | 
				
			||||||
 | 
						unsigned long h = 0;
 | 
				
			||||||
 | 
						while (*k) {
 | 
				
			||||||
 | 
							h = (h << 4) + *k++;
 | 
				
			||||||
 | 
							unsigned long g = h & 0xF0000000L;
 | 
				
			||||||
 | 
							if (g) {
 | 
				
			||||||
 | 
								h ^= g >> 24;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							h &= ~g;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return h % hashMap->listSize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Boolean defaultEqual(let key1, let key2) {
 | 
				
			||||||
 | 
						return strcmp((string)key1, (string)key2) ? False : True;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void resetHashMap(HashMap hashMap, int listSize) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (listSize < 8) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 键值对临时存储空间
 | 
				
			||||||
 | 
						Entry tempList = newEntryList(hashMap->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HashMapIterator iterator = createHashMapIterator(hashMap);
 | 
				
			||||||
 | 
						int length = hashMap->size;
 | 
				
			||||||
 | 
						for (int index = 0; hasNextHashMapIterator(iterator); index++) {
 | 
				
			||||||
 | 
							// 迭代取出所有键值对
 | 
				
			||||||
 | 
							iterator = nextHashMapIterator(iterator);
 | 
				
			||||||
 | 
							tempList[index].key = iterator->entry->key;
 | 
				
			||||||
 | 
							tempList[index].value = iterator->entry->value;
 | 
				
			||||||
 | 
							tempList[index].next = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						freeHashMapIterator(&iterator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 清除原有键值对数据
 | 
				
			||||||
 | 
						hashMap->size = 0;
 | 
				
			||||||
 | 
						for (int i = 0; i < hashMap->listSize; i++) {
 | 
				
			||||||
 | 
							Entry current = &hashMap->list[i];
 | 
				
			||||||
 | 
							current->key = NULL;
 | 
				
			||||||
 | 
							current->value = NULL;
 | 
				
			||||||
 | 
							if (current->next != NULL) {
 | 
				
			||||||
 | 
								while (current->next != NULL) {
 | 
				
			||||||
 | 
									Entry temp = current->next->next;
 | 
				
			||||||
 | 
									free(current->next);
 | 
				
			||||||
 | 
									current->next = temp;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 更改内存大小
 | 
				
			||||||
 | 
						hashMap->listSize = listSize;
 | 
				
			||||||
 | 
						Entry relist = (Entry)realloc(hashMap->list, hashMap->listSize * sizeof(struct entry));
 | 
				
			||||||
 | 
						if (relist != NULL) {
 | 
				
			||||||
 | 
							hashMap->list = relist;
 | 
				
			||||||
 | 
							relist = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 初始化数据
 | 
				
			||||||
 | 
						for (int i = 0; i < hashMap->listSize; i++) {
 | 
				
			||||||
 | 
							hashMap->list[i].key = NULL;
 | 
				
			||||||
 | 
							hashMap->list[i].value = NULL;
 | 
				
			||||||
 | 
							hashMap->list[i].next = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 将所有键值对重新写入内存
 | 
				
			||||||
 | 
						for (int i = 0; i < length; i++) {
 | 
				
			||||||
 | 
							hashMap->put(hashMap, tempList[i].key, tempList[i].value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(tempList);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void defaultPut(HashMap hashMap, let key, let value) {
 | 
				
			||||||
 | 
						// 获取哈希值
 | 
				
			||||||
 | 
						int index = hashMap->hashCode(hashMap, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hashMap->list[index].key == NULL) {
 | 
				
			||||||
 | 
							hashMap->size++;
 | 
				
			||||||
 | 
							// 该地址为空时直接存储
 | 
				
			||||||
 | 
							hashMap->list[index].key = key;
 | 
				
			||||||
 | 
							hashMap->list[index].value = value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Entry current = &hashMap->list[index];
 | 
				
			||||||
 | 
							while (current != NULL) {
 | 
				
			||||||
 | 
								if (hashMap->equal(key, current->key)) {
 | 
				
			||||||
 | 
									// 对于键值已经存在的直接覆盖
 | 
				
			||||||
 | 
									current->value = value;
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								current = current->next;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 发生冲突则创建节点挂到相应位置的next上
 | 
				
			||||||
 | 
							Entry entry = newEntry();
 | 
				
			||||||
 | 
							entry->key = key;
 | 
				
			||||||
 | 
							entry->value = value;
 | 
				
			||||||
 | 
							entry->next = hashMap->list[index].next;
 | 
				
			||||||
 | 
							hashMap->list[index].next = entry;
 | 
				
			||||||
 | 
							hashMap->size++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 内存扩充至原来的两倍
 | 
				
			||||||
 | 
							// *注: 扩充时考虑的是当前存储元素数量与存储空间的大小关系,而不是存储空间是否已经存满,
 | 
				
			||||||
 | 
							// 例如: 存储空间为10,存入了10个键值对,但是全部冲突了,所以存储空间空着9个,其余的全部挂在一个上面,
 | 
				
			||||||
 | 
							// 这样检索的时候和遍历查询没有什么区别了,可以简单这样理解,当我存入第11个键值对的时候一定会发生冲突,
 | 
				
			||||||
 | 
							// 这是由哈希函数本身的特性(取模)决定的,冲突就会导致检索变慢,所以这时候扩充存储空间,对原有键值对进行
 | 
				
			||||||
 | 
							// 再次散列,会把冲突的数据再次分散开,加快索引定位速度。
 | 
				
			||||||
 | 
							resetHashMap(hashMap, hashMap->listSize * 2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let defaultGet(HashMap hashMap, let key) {
 | 
				
			||||||
 | 
						if (hashMap->exists(hashMap, key)) {
 | 
				
			||||||
 | 
							int index = hashMap->hashCode(hashMap, key);
 | 
				
			||||||
 | 
							Entry entry = &hashMap->list[index];
 | 
				
			||||||
 | 
							while (entry != NULL) {
 | 
				
			||||||
 | 
								if (hashMap->equal(entry->key, key)) {
 | 
				
			||||||
 | 
									return entry->value;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								entry = entry->next;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let defaultRemove(HashMap hashMap, let key) {
 | 
				
			||||||
 | 
						int index = hashMap->hashCode(hashMap, key);
 | 
				
			||||||
 | 
						Entry entry = &hashMap->list[index];
 | 
				
			||||||
 | 
						if (entry->key == NULL) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    let entryKey = entry->key;
 | 
				
			||||||
 | 
						Boolean result = False;
 | 
				
			||||||
 | 
						if (hashMap->equal(entry->key, key)) {
 | 
				
			||||||
 | 
							hashMap->size--;
 | 
				
			||||||
 | 
							if (entry->next != NULL) {
 | 
				
			||||||
 | 
								Entry temp = entry->next;
 | 
				
			||||||
 | 
								entry->key = temp->key;
 | 
				
			||||||
 | 
								entry->value = temp->value;
 | 
				
			||||||
 | 
								entry->next = temp->next;
 | 
				
			||||||
 | 
								free(temp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            entry->key = NULL;
 | 
				
			||||||
 | 
					            entry->value = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
							result = True;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							Entry p = entry;
 | 
				
			||||||
 | 
							entry = entry->next;
 | 
				
			||||||
 | 
							while (entry != NULL) {
 | 
				
			||||||
 | 
								if (hashMap->equal(entry->key, key)) {
 | 
				
			||||||
 | 
									hashMap->size--;
 | 
				
			||||||
 | 
									p->next = entry->next;
 | 
				
			||||||
 | 
									free(entry);
 | 
				
			||||||
 | 
									result = True;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								p = entry;
 | 
				
			||||||
 | 
								entry = entry->next;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 如果空间占用不足一半,则释放多余内存
 | 
				
			||||||
 | 
						if (result && hashMap->autoAssign &&  hashMap->size < hashMap->listSize / 2) {
 | 
				
			||||||
 | 
							resetHashMap(hashMap, hashMap->listSize / 2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return entryKey;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Boolean defaultExists(HashMap hashMap, let key) {
 | 
				
			||||||
 | 
						int index = hashMap->hashCode(hashMap, key);
 | 
				
			||||||
 | 
						Entry entry = &hashMap->list[index];
 | 
				
			||||||
 | 
						if (entry->key == NULL) {
 | 
				
			||||||
 | 
							return False;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							while (entry != NULL) {
 | 
				
			||||||
 | 
								if (hashMap->equal(entry->key, key)) {
 | 
				
			||||||
 | 
									return True;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								entry = entry->next;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return False;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void defaultClear(HashMap hashMap) {
 | 
				
			||||||
 | 
						for (int i = 0; i < hashMap->listSize; i++) {
 | 
				
			||||||
 | 
							// 释放冲突值内存
 | 
				
			||||||
 | 
							Entry entry = hashMap->list[i].next;
 | 
				
			||||||
 | 
							while (entry != NULL) {
 | 
				
			||||||
 | 
								Entry next = entry->next;
 | 
				
			||||||
 | 
								free(entry);
 | 
				
			||||||
 | 
								entry = next;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							hashMap->list[i].next = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 释放存储空间
 | 
				
			||||||
 | 
						free(hashMap->list);
 | 
				
			||||||
 | 
						hashMap->list = NULL;
 | 
				
			||||||
 | 
						hashMap->size = -1;
 | 
				
			||||||
 | 
						hashMap->listSize = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HashMap createHashMap(HashCode hashCode, Equal equal) {
 | 
				
			||||||
 | 
						HashMap hashMap = newHashMap();
 | 
				
			||||||
 | 
						if (hashMap == NULL) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hashMap->size = 0;
 | 
				
			||||||
 | 
						hashMap->listSize = 8;
 | 
				
			||||||
 | 
						hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode;
 | 
				
			||||||
 | 
						hashMap->equal = equal == NULL ? defaultEqual : equal;
 | 
				
			||||||
 | 
						hashMap->exists = defaultExists;
 | 
				
			||||||
 | 
						hashMap->get = defaultGet;
 | 
				
			||||||
 | 
						hashMap->put = defaultPut;
 | 
				
			||||||
 | 
						hashMap->remove = defaultRemove;
 | 
				
			||||||
 | 
						hashMap->clear = defaultClear;
 | 
				
			||||||
 | 
						hashMap->autoAssign = True;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// 起始分配8个内存空间,溢出时会自动扩充
 | 
				
			||||||
 | 
						hashMap->list = newEntryList(hashMap->listSize);
 | 
				
			||||||
 | 
						if (hashMap->list == NULL) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Entry p = hashMap->list;
 | 
				
			||||||
 | 
						for (int i = 0; i < hashMap->listSize; i++) {
 | 
				
			||||||
 | 
							p[i].key = p[i].value = p[i].next = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return hashMap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HashMapIterator createHashMapIterator(HashMap hashMap) {
 | 
				
			||||||
 | 
						HashMapIterator iterator = newHashMapIterator();
 | 
				
			||||||
 | 
						if (iterator == NULL) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						iterator->hashMap = hashMap;
 | 
				
			||||||
 | 
						iterator->count = 0;
 | 
				
			||||||
 | 
						iterator->hashCode = -1;
 | 
				
			||||||
 | 
						iterator->entry = NULL;
 | 
				
			||||||
 | 
						return iterator;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Boolean hasNextHashMapIterator(HashMapIterator iterator) {
 | 
				
			||||||
 | 
						return iterator->count < iterator->hashMap->size ? True : False;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HashMapIterator nextHashMapIterator(HashMapIterator iterator) {
 | 
				
			||||||
 | 
						if (hasNextHashMapIterator(iterator)) {
 | 
				
			||||||
 | 
							if (iterator->entry != NULL && iterator->entry->next != NULL) {
 | 
				
			||||||
 | 
								iterator->count++;
 | 
				
			||||||
 | 
								iterator->entry = iterator->entry->next;
 | 
				
			||||||
 | 
								return iterator;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (++iterator->hashCode < iterator->hashMap->listSize) {
 | 
				
			||||||
 | 
								Entry entry = &iterator->hashMap->list[iterator->hashCode];
 | 
				
			||||||
 | 
								if (entry->key != NULL) {
 | 
				
			||||||
 | 
									iterator->count++;
 | 
				
			||||||
 | 
									iterator->entry = entry;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return iterator;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void freeHashMapIterator(HashMapIterator * iterator) {
 | 
				
			||||||
 | 
						free(*iterator);
 | 
				
			||||||
 | 
						*iterator = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define Put(map, key, value) map->put(map, (void *)key, (void *)value);
 | 
				
			||||||
 | 
					#define Get(map, key) (char *)map->get(map, (void *)key)
 | 
				
			||||||
 | 
					#define Remove(map, key) map->remove(map, (void *)key)
 | 
				
			||||||
 | 
					#define Existe(map, key) map->exists(map, (void *)key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestHash() {
 | 
				
			||||||
 | 
					    HashMap map = createHashMap(NULL, NULL);
 | 
				
			||||||
 | 
					    Put(map, "000123", "Annie");
 | 
				
			||||||
 | 
					    Put(map, "000245", "Bob");
 | 
				
			||||||
 | 
					    Put(map, "000284", "Daniel");
 | 
				
			||||||
 | 
					    Put(map, "000281", "Luna");
 | 
				
			||||||
 | 
					    Put(map, "000587", "Yao");
 | 
				
			||||||
 | 
					    Put(map, "000985", "Li Ming");
 | 
				
			||||||
 | 
					    Put(map, "000852", "Janne");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("print the key-values in hashmap:\n");
 | 
				
			||||||
 | 
					    HashMapIterator iterator = createHashMapIterator(map);
 | 
				
			||||||
 | 
					    while (hasNextHashMapIterator(iterator)) {
 | 
				
			||||||
 | 
					        iterator = nextHashMapIterator(iterator);
 | 
				
			||||||
 | 
					        printf("{ key: %s, key: %s, hashcode: %d }\n",
 | 
				
			||||||
 | 
					            (char *)iterator->entry->key, (char *)iterator->entry->value, iterator->hashCode);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false");
 | 
				
			||||||
 | 
					    printf("000852: %s\n", Get(map, "000852"));
 | 
				
			||||||
 | 
					    printf("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false");
 | 
				
			||||||
 | 
					    printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    map->clear(map);
 | 
				
			||||||
 | 
					    freeHashMapIterator(&iterator);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PRIV_SHELL_CMD_FUNCTION(TestHash, Implement hash_map, PRIV_SHELL_CMD_MAIN_ATTR);
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,129 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* @file:    test_hash.h
 | 
				
			||||||
 | 
					* @brief:   a application of test hash function
 | 
				
			||||||
 | 
					* @version: 3.0
 | 
				
			||||||
 | 
					* @author:  Yao wenying
 | 
				
			||||||
 | 
					* @date:    2023/05/26
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __HASHMAP_H__
 | 
				
			||||||
 | 
					#define __HASHMAP_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include<stdlib.h>
 | 
				
			||||||
 | 
					#include<string.h>
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 实现数据的基本类型
 | 
				
			||||||
 | 
					// 字符串类型
 | 
				
			||||||
 | 
					#define string char *
 | 
				
			||||||
 | 
					#define newString(str) strcpy((char *)malloc(strlen(str) + 1), str)
 | 
				
			||||||
 | 
					#define NEW(type) (type *)malloc(sizeof(type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 布尔类型
 | 
				
			||||||
 | 
					enum _Boolean { True = 1, False = 0 };
 | 
				
			||||||
 | 
					typedef enum _Boolean  Boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define let void *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct entry {
 | 
				
			||||||
 | 
						let key;				// 键
 | 
				
			||||||
 | 
						let value;				// 值
 | 
				
			||||||
 | 
						struct entry * next;	// 冲突链表
 | 
				
			||||||
 | 
					}*Entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define newEntry() NEW(struct entry)
 | 
				
			||||||
 | 
					#define newEntryList(length) (Entry)malloc(length * sizeof(struct entry))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 哈希结构
 | 
				
			||||||
 | 
					typedef struct hashMap *HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define newHashMap() NEW(struct hashMap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 哈希函数类型
 | 
				
			||||||
 | 
					typedef int(*HashCode)(HashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判等函数类型
 | 
				
			||||||
 | 
					typedef Boolean(*Equal)(let key1, let key2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加键函数类型
 | 
				
			||||||
 | 
					typedef void(*Put)(HashMap hashMap, let key, let value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取键对应值的函数类型
 | 
				
			||||||
 | 
					typedef let(*Get)(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 删除键的函数类型
 | 
				
			||||||
 | 
					typedef let(*Remove)(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 清空Map的函数类型
 | 
				
			||||||
 | 
					typedef void(*Clear)(HashMap hashMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断键值是否存在的函数类型
 | 
				
			||||||
 | 
					typedef Boolean(*Exists)(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct hashMap {
 | 
				
			||||||
 | 
						int size;			// 当前大小
 | 
				
			||||||
 | 
						int listSize;		// 有效空间大小
 | 
				
			||||||
 | 
						HashCode hashCode;	// 哈希函数
 | 
				
			||||||
 | 
						Equal equal;		// 判等函数
 | 
				
			||||||
 | 
						Entry list;			// 存储区域
 | 
				
			||||||
 | 
						Put put;			// 添加键的函数
 | 
				
			||||||
 | 
						Get get;			// 获取键对应值的函数
 | 
				
			||||||
 | 
						Remove remove;		// 删除键
 | 
				
			||||||
 | 
						Clear clear;		// 清空Map
 | 
				
			||||||
 | 
						Exists exists;		// 判断键是否存在
 | 
				
			||||||
 | 
						Boolean autoAssign;	// 设定是否根据当前数据量动态调整内存大小,默认开启
 | 
				
			||||||
 | 
					}*HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 迭代器结构
 | 
				
			||||||
 | 
					typedef struct hashMapIterator {
 | 
				
			||||||
 | 
						Entry entry;	// 迭代器当前指向
 | 
				
			||||||
 | 
						int count;		// 迭代次数
 | 
				
			||||||
 | 
						int hashCode;	// 键值对的哈希值
 | 
				
			||||||
 | 
						HashMap hashMap;
 | 
				
			||||||
 | 
					}*HashMapIterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define newHashMapIterator() NEW(struct hashMapIterator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认哈希函数
 | 
				
			||||||
 | 
					static int defaultHashCode(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认判断键值是否相等
 | 
				
			||||||
 | 
					static Boolean defaultEqual(let key1, let key2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认添加键值对
 | 
				
			||||||
 | 
					static void defaultPut(HashMap hashMap, let key, let value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认获取键对应值
 | 
				
			||||||
 | 
					static let defaultGet(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认删除键
 | 
				
			||||||
 | 
					static let defaultRemove(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认判断键是否存在
 | 
				
			||||||
 | 
					static Boolean defaultExists(HashMap hashMap, let key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认清空Map
 | 
				
			||||||
 | 
					static void defaultClear(HashMap hashMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 重新构建
 | 
				
			||||||
 | 
					static void resetHashMap(HashMap hashMap, int listSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 创建一个哈希结构
 | 
				
			||||||
 | 
					HashMap createHashMap(HashCode hashCode, Equal equal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 创建哈希结构迭代器
 | 
				
			||||||
 | 
					HashMapIterator createHashMapIterator(HashMap hashMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 迭代器是否有下一个
 | 
				
			||||||
 | 
					Boolean hasNextHashMapIterator(HashMapIterator iterator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 迭代到下一次
 | 
				
			||||||
 | 
					HashMapIterator nextHashMapIterator(HashMapIterator iterator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 释放迭代器内存
 | 
				
			||||||
 | 
					void freeHashMapIterator(HashMapIterator * iterator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !__HASHMAP_H__
 | 
				
			||||||
		Loading…
	
		Reference in New Issue