diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 45df5f5d5..576dd4a38 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -239,6 +239,10 @@ menu "test app" menuconfig USER_TEST_TIMER bool "Config test soft timer" default n + + menuconfig USER_TEST_HASH + bool "Config test HASH CONFLICT SAMPLE" + default n endif endmenu diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 1cf919846..d7afc9d28 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -99,7 +99,11 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) ifeq ($(CONFIG_USER_TEST_TIMER),y) SRC_FILES += test_timer.c - endif + endif + + ifeq ($(CONFIG_USER_TEST_HASH),y) + SRC_FILES += test_hash/test_hash.c + endif include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_hash/Initialization.jpg b/APP_Framework/Applications/app_test/test_hash/Initialization.jpg new file mode 100644 index 000000000..eb93f07ac Binary files /dev/null and b/APP_Framework/Applications/app_test/test_hash/Initialization.jpg differ diff --git a/APP_Framework/Applications/app_test/test_hash/README.md b/APP_Framework/Applications/app_test/test_hash/README.md new file mode 100644 index 000000000..8506e77e5 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/README.md @@ -0,0 +1,47 @@ +# 热身赛一级赛题1:基于cortex-m3-emulator实现哈希表并测试验证## + +## 1. 简介 +该程序是一个关于哈希表的设计和测试程序。哈希表是一种常用的数据结构,用于快速存储和查找键值对。本项目提供了哈希表的基本操作函数和测试程序。 + + +## 2. 数据结构设计说明 +本项目的数据结构设计包括以下两个主要结构: + +**HashNode 结构** +HashNode 结构表示哈希表中的节点,包含以下字段: + +* key:键值对的键 +* value:键值对的值 +* next:指向下一个节点的指针 + +**HashTable 结构** +HashTable 结构表示整个哈希表,包含以下字段: + +* size:哈希表的大小(桶的数量) +* table:指向哈希表桶数组的指针 + +哈希表使用链地址法来处理哈希冲突,每个桶存储一个链表,通过节点的 next 指针连接节点。 + + +## 3. 测试程序说明 +测试程序提供了对哈希表的基本操作的测试。具体步骤如下: + +1. 初始化哈希表 +2. 向哈希表插入键值对,打印哈希表,展示哈希冲突情况 +3. 查找指定键的值 +4. 删除指定键的节点 +5. 销毁哈希表 + + +## 4. 运行结果 +1. shell中输入TestHash初始化哈希表: +![结点](./Initialization.jpg) +2. test_hash.c文件中已经写好键值对,打印并展示哈希冲突情况: +![结点](./print1.jpg) +3. 查找键为1的键值对,已知哈希表中key=1,value=1: +![结点](./search.jpg) +4. 删除键key=222,value=222的键值对,打印并查看删除情况: +![结点](./deletion.jpg) +5. 销毁哈希表: +![结点](./destroy.jpg) + diff --git a/APP_Framework/Applications/app_test/test_hash/deletion.jpg b/APP_Framework/Applications/app_test/test_hash/deletion.jpg new file mode 100644 index 000000000..2f750a1bb Binary files /dev/null and b/APP_Framework/Applications/app_test/test_hash/deletion.jpg differ diff --git a/APP_Framework/Applications/app_test/test_hash/destroy.jpg b/APP_Framework/Applications/app_test/test_hash/destroy.jpg new file mode 100644 index 000000000..ce4d70cb6 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_hash/destroy.jpg differ diff --git a/APP_Framework/Applications/app_test/test_hash/print1.jpg b/APP_Framework/Applications/app_test/test_hash/print1.jpg new file mode 100644 index 000000000..bfc06ce0c Binary files /dev/null and b/APP_Framework/Applications/app_test/test_hash/print1.jpg differ diff --git a/APP_Framework/Applications/app_test/test_hash/search.jpg b/APP_Framework/Applications/app_test/test_hash/search.jpg new file mode 100644 index 000000000..7e3efb1d3 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_hash/search.jpg differ diff --git a/APP_Framework/Applications/app_test/test_hash/test_hash.c b/APP_Framework/Applications/app_test/test_hash/test_hash.c new file mode 100644 index 000000000..ae958cccb --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.c @@ -0,0 +1,157 @@ +#include +#include +#include "test_hash.h" +#include + +// 哈希函数,根据键值计算哈希值 +int hashFunction(int key, int size) { + return key % size; +} + +// 初始化哈希表 +void hashTableInit(HashTable* ht, int size) { + ht->size = size; + ht->table = (HashNode**)malloc(size * sizeof(HashNode*)); + for (int i = 0; i < size; i++) { + ht->table[i] = NULL; + } +} + +// 向哈希表插入键值对 +void hashTableInsert(HashTable* ht, int key, int value) { + int index = hashFunction(key, ht->size); + HashNode* newNode = (HashNode*)malloc(sizeof(HashNode)); + newNode->key = key; + newNode->value = value; + newNode->next = NULL; + + // 非哈希冲突 + if (ht->table[index] == NULL) { + ht->table[index] = newNode; + } + // 哈希冲突 + else { + HashNode* curr = ht->table[index]; + while (curr->next != NULL) { + curr = curr->next; + } + curr->next = newNode; + } +} + +// 从哈希表中查找指定键的值 +int hashTableGet(HashTable* ht, int key) { + int index = hashFunction(key, ht->size); + HashNode* curr = ht->table[index]; + while (curr != NULL) { + if (curr->key == key) { + return curr->value; + } + curr = curr->next; + } + return -1; // 未找到对应的键 +} + +// 从哈希表中删除指定键的节点 +void hashTableRemove(HashTable* ht, int key) { + int index = hashFunction(key, ht->size); + + //表空,无需删除 + if(ht->table[index] == NULL){ + return; + } + + //删除为头节点 + if(ht->table[index]->key == key){ + HashNode *tempNode = (HashNode *)malloc(sizeof(HashNode)); + tempNode = ht->table[index]; + ht->table[index] = ht->table[index]->next; + free(tempNode); + return; + } + + //需要查找,再删除 + HashNode* tempNode = (HashNode *)malloc(sizeof(HashNode)); + tempNode = ht->table[index]; + //从头节点的下一节点开始遍历 + while (tempNode->next != NULL && tempNode->next->key != key){ + tempNode = tempNode->next; + } + //如果找到节点 + if(tempNode->next != NULL){ + HashNode* node = tempNode->next; + tempNode->next = tempNode->next->next; + free(node); + } +} + +// 销毁哈希表 +void hashTableDestroy(HashTable* ht) { + for (int i = 0; i < ht->size; i++) { + HashNode* curr = ht->table[i]; + while (curr != NULL) { + HashNode* temp = curr; + curr = curr->next; + free(temp); + } + } + free(ht->table); +} + +// 打印哈希表 +void printHashTable(HashTable* ht) { + for (int i = 0; i < TABLE_SIZE; i++) { + HashNode* curr = ht->table[i]; + while (curr != NULL) { + printf("(index, key, value): (%d ,%d, %d) ",i ,curr->key, curr->value); + curr = curr->next; + printf("\n"); + } + } +} +void TestHash(){ + HashTable ht; + // char input[10] = {0}; + // 哈希表初始化 + hashTableInit(&ht, TABLE_SIZE); + printf("Hash table initialization succeeded with a length of TABLE_SIZE.\n"); + + + // printf("input->"); + // PrivTaskDelay(500); + // setvbuf(stdin, NULL, _IONBF, 0); + // fgets(input, sizeof(input), stdin); + // scanf("%[^\n]",input); + // printf("\ninput=%s\n",input); + + // 插入键值对 + hashTableInsert(&ht, 1, 1); + hashTableInsert(&ht, 11, 11); + hashTableInsert(&ht, 22, 22); + + // 哈希冲突 + hashTableInsert(&ht, 101, 101); + hashTableInsert(&ht, 111, 111); + hashTableInsert(&ht, 222, 222); + + printf("Intial Hush Table, then you can see conflics of Hush table below: \n"); + printHashTable(&ht); + + // 查找键对应的值 + int value1 = hashTableGet(&ht, 1); + printf("Search key=1: %d\n", value1); // 输出:Value for key 1: 1 + + // 删除键对 + hashTableRemove(&ht, 222); + printf("Successfully completed the deletion of data with key = 222\n"); + + //打印哈希表 + printHashTable(&ht); + printf("The key-value pair with (key=222,value=222) has been deleted successfully.\n"); + + // 销毁哈希表 + hashTableDestroy(&ht); + printf("Hash table destroyed successfully! \n"); +} + +PRIV_SHELL_CMD_FUNCTION(TestHash, a Hash conflic test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_hash/test_hash.h b/APP_Framework/Applications/app_test/test_hash/test_hash.h new file mode 100644 index 000000000..908eae2aa --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.h @@ -0,0 +1,37 @@ +#ifndef TEST_HASH_H +#define TEST_HASH_H + +#define TABLE_SIZE 100 + +// 定义哈希表节点结构 +typedef struct HashNode { + int key; + int value; + struct HashNode* next; +} HashNode; + +// 定义哈希表结构 +typedef struct HashTable { + int size; + HashNode** table; +} HashTable; + +// 初始化哈希表 +void hashTableInit(HashTable* ht, int size); + +// 向哈希表插入键值对 +void hashTableInsert(HashTable* ht, int key, int value); + +// 从哈希表中查找指定键的值 +int hashTableGet(HashTable* ht, int key); + +// 从哈希表中删除指定键的节点 +void hashTableRemove(HashTable* ht, int key); + +// 销毁哈希表 +void hashTableDestroy(HashTable* ht); + +// 打印哈希表 +void printHashTable(HashTable* ht); + +#endif