diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 45df5f5d5..1298d10b5 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" + default n endif endmenu diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 1cf919846..bb4d07809 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -101,5 +101,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_timer.c 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/README.md b/APP_Framework/Applications/app_test/test_hash/README.md new file mode 100644 index 000000000..91dae0801 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/README.md @@ -0,0 +1,79 @@ +# 基于cortex-m3-emulator实现哈希表并测试验证 + +## 1. 简介 +基于cortex-m3-emulator实现链式哈希表,并设计了几个小数据集测试其功能 + + +## 2. 数据结构设计说明 + +```c +typedef struct Node{ + int key; + int value; + struct Node *next; +} Node; + +typedef struct HashTable{ + Node *table[TABLE_SIZE]; +} HashTable; +``` + +每一个节点都是一个Node, 分别存储键值对,以及相同哈希值的下一个节点。 + +HashTable为一个Node指针数组,存储每个Hash值的链表的首地址。 + +## 3. 测试程序说明 + +```c +void TestHash(void) +{ + HashTable table; + Init(&table); + + printf("Test Hash Table\n"); + printf("Insert 1, 10\n"); + Insert(&table, 1, 10); + printf("Insert 2, 20\n"); + Insert(&table, 2, 20); + printf("Insert 3, 30\n"); + Insert(&table, 3, 30); + printf("Insert 101, 40\n"); + Insert(&table, 101, 40); + printf("Insert 102, 50\n"); + Insert(&table, 102, 50); + printf("Insert 103, 60\n"); + Insert(&table, 103, 60); + printf("Insert 104, 70\n"); + Insert(&table, 104, 70); + + printf("Search 1, result: %d\n", Search(&table, 1)); + printf("Search 2, result: %d\n", Search(&table, 2)); + printf("Search 3, result: %d\n", Search(&table, 3)); + printf("Search 4, result: %d\n", Search(&table, 4)); + printf("Search 101, result: %d\n", Search(&table, 101)); + printf("Search 102, result: %d\n", Search(&table, 102)); + printf("Search 103, result: %d\n", Search(&table, 103)); + printf("Search 104, result: %d\n", Search(&table, 104)); + + printf("Delete 1\n"); + Delete(&table, 1); + + printf("Search 1, result: %d\n", Search(&table, 1)); + + printf("Clear Table\n"); + Clear(&table); + + return; +} +``` + +首先利用Init函数初始化HashTable,然后插入一系列值,对于101同余的Key具有相同的哈希值,会被放入同一个bucket当中。随后查找几个值,都符合预期(如果查找不到则返回值为-1,此处认为用户应该不会存储负数的value,若会存储负数的value,可将不存在的标记修改一下)。然后删除一个节点重新查找,应当查找不到,最后释放哈希表的空间。 + +## 4. 运行结果(##需结合运行测试截图按步骤说明##) + +首先启动机器 + +![2023_open_source_contest_warmup_1st_issue1_1](https://xubbbb-chartbed.oss-cn-shanghai.aliyuncs.com/img/markdown/2023_open_source_contest_warmup_1st_issue1_1.png) + +运行TestHash命令 +![2023_open_source_contest_warmup_1st_issue1_2](https://xubbbb-chartbed.oss-cn-shanghai.aliyuncs.com/img/markdown/2023_open_source_contest_warmup_1st_issue1_2.png) 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..c45fb19dc --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.c @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: test_hash.c +* @brief: a application to test hash table and print result +* @version: 1.1 +* @author: LeviXubbbb(Bin Xu) +* @date: 2023/06/22 +*/ + +#include +#include +#include +#include +#include "test_hash.h" +#ifdef ADD_XIZI_FETURES + +void TestHash(void) +{ + HashTable table; + + printf("Init Hash Table\n"); + Init(&table); + + printf("Test Hash Table\n"); + printf("Insert 1, 10\n"); + Insert(&table, 1, 10); + printf("Insert 2, 20\n"); + Insert(&table, 2, 20); + printf("Insert 3, 30\n"); + Insert(&table, 3, 30); + printf("Insert 101, 40\n"); + Insert(&table, 101, 40); + printf("Insert 102, 50\n"); + Insert(&table, 102, 50); + printf("Insert 103, 60\n"); + Insert(&table, 103, 60); + printf("Insert 104, 70\n"); + Insert(&table, 104, 70); + + printf("Search 1, result: %d\n", Search(&table, 1)); + printf("Search 2, result: %d\n", Search(&table, 2)); + printf("Search 3, result: %d\n", Search(&table, 3)); + printf("Search 4, result: %d\n", Search(&table, 4)); + printf("Search 101, result: %d\n", Search(&table, 101)); + printf("Search 102, result: %d\n", Search(&table, 102)); + printf("Search 103, result: %d\n", Search(&table, 103)); + printf("Search 104, result: %d\n", Search(&table, 104)); + + printf("Delete 1\n"); + Delete(&table, 1); + + printf("Search 1, result: %d\n", Search(&table, 1)); + + printf("Clear Table\n"); + Clear(&table); + + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestHash, a hash table test sample, PRIV_SHELL_CMD_MAIN_ATTR); +#endif \ 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..20ea6ea34 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.h @@ -0,0 +1,116 @@ +#ifndef XIUOS_TEST_HASH_H +#define XIUOS_TEST_HASH_H + +#include +#include +#include + +#define TABLE_SIZE 101 + +typedef struct Node{ + int key; + int value; + struct Node *next; +} Node; + +typedef struct HashTable{ + Node *table[TABLE_SIZE]; +} HashTable; + +unsigned int Hash(int key) +{ + return key % TABLE_SIZE; +} + +Node* CreateNode(int key, int value) +{ + Node *new_node = (Node*)malloc(sizeof(Node)); + new_node->key = key; + new_node->value = value; + new_node->next = NULL; + return new_node; +} + +void Init(HashTable *hash_table) +{ + int i; + for(i = 0; i < TABLE_SIZE; i++) + hash_table->table[i] = NULL; +} + +void Insert(HashTable *hash_table, int key, int value) +{ + unsigned int hash_value = Hash(key); + + Node *node = hash_table->table[hash_value]; + while(node != NULL && node->key != key) + node = node->next; + if(node != NULL){ + node->value = value; + return; + } + + Node *new_node = CreateNode(key, value); + new_node->next = hash_table->table[hash_value]; + hash_table->table[hash_value] = new_node; +} + +int Search(HashTable *hash_table, int key) +{ + unsigned int hash_value = Hash(key); + Node *node = hash_table->table[hash_value]; + while(node != NULL && node->key != key) + node = node->next; + if(node == NULL) + return -1; + else + return node->value; +} + +void Delete(HashTable *hash_table, int key) +{ + unsigned int hash_value = Hash(key); + Node *node = hash_table->table[hash_value]; + Node *prev_node = NULL; + while(node != NULL && node->key != key){ + prev_node = node; + node = node->next; + } + if(node == NULL) + return; + if(prev_node == NULL) + hash_table->table[hash_value] = node->next; + else + prev_node->next = node->next; + free(node); +} + +void Clear(HashTable *hash_table) +{ + int i; + for(i = 0; i < TABLE_SIZE; i++){ + Node *node = hash_table->table[i]; + while(node != NULL){ + Node *temp = node; + node = node->next; + free(temp); + } + hash_table->table[i] = NULL; + } +} + +void PrintTable(HashTable *hash_table) +{ + int i; + for(i = 0; i < TABLE_SIZE; i++){ + printf("Print %d\n", i); + Node *node = hash_table->table[i]; + while(node != NULL){ + printf("key: %d, value: %d\n", node->key, node->value); + node = node->next; + } + } +} + + +#endif //XIUOS_TEST_HASH_H \ No newline at end of file