This commit is contained in:
cryindevil 2023-06-30 00:08:22 +08:00
parent 7754a149a9
commit 385a52ab24
6 changed files with 383 additions and 1 deletions

View File

@ -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 y
endif
endmenu

View File

@ -100,6 +100,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
ifeq ($(CONFIG_USER_TEST_TIMER),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

View File

@ -0,0 +1,156 @@
# ##基于cortex-m3-emulator实现哈希表并测试验证##
## 1. 简介
实现哈希表支持链地址法解决哈希冲突并编写测试程序在shell终端打印结果
因为没有说明哈希的具体实现完成程度,以个人理解程度实现,以熟悉热身为目的
## 2. 数据结构设计说明
```C
#define TABLE_SIZE 10//哈希表的长度,使用宏定义,有需要可直接更改
typedef struct Node {
int key;
int value;
struct Node* next;
} Node;//一个结点的数据类型包含key,value,和指向下一个结点的指针
typedef struct HashTable {
Node** table; // 存储链表头指针的数组
} HashTable;
```
## 3. 测试程序说明
包含两大部分函数
1初始化链表使用的函数
```C
//创建一个结点,在添加键值对时使用
Node* createNode(int key, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
return newNode;
}
//初始化哈希表
HashTable* createHashTable() {
HashTable* hashTable = (HashTable*)malloc(sizeof(HashTable));
hashTable->table = (Node**)calloc(TABLE_SIZE, sizeof(Node*));
return hashTable;
}
// 哈希函数,计算键的索引
int hashFunction(int key) {
return key % TABLE_SIZE;
}
```
2对链表进行更改的函数共五个操作即五个函数
```C
// 在哈希表中插入键值对
void insert(HashTable* hashTable, int key, int value) {
int index = hashFunction(key);
Node* newNode = createNode(key, value);
if (hashTable->table[index] == NULL) {
hashTable->table[index] = newNode;
} else {
Node* current = hashTable->table[index];
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
// 在哈希表中查找是否有该键有则返回1无则返回0
int find(HashTable* hashTable, int key) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key) {
return 1;
}
current = current->next;
}
return 0;
}
// 在哈希表中查找键对应的值,找到返回键对应的值,如果未找到返回-1
int get(HashTable* hashTable, int key) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key) {
return current->value;
}
current = current->next;
}
return -1;
}
//将某一键值对的值改变为新的值修改成功返回1如果未找到该键值对返回0
int change(HashTable* hashTable, int key , int oldValue , int newValue) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key && current->value == oldValue) {
current->value = newValue;
return 1;
}
current = current->next;
}
return 0;
}
//删除某一键值对删除成功返回1如果未找到该键值对返回0
int deleteNode(HashTable* hashTable, int key , int value ) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
Node* last = current;
if(current != NULL){
if (current->key == key && current->value == value){
hashTable->table[index] = current->next;
free(current);
return 1;
}
current = current->next;
}
while (current != NULL) {
if (current->key == key && current->value == value) {
last->next=current->next;
free(current);
return 1;
}
last = current;
current = current->next;
}
return 0;
}
```
### 测试思路:(测试代码即test_hash()函数中内容)
1初始化了哈希表随机选取了四个键值对进行插入
2测试通过键寻找值分成两种情况找到和未找到
3修改键值对的值若找到键值对输出新的值若找不到显示未找到该键值对
4删除特定键值对同时证明对后续结点不产生影响
## 4. 运行结果(##需结合运行测试截图按步骤说明##
![screenshot](screen.png)
1. 第一部分 插入了四个键值对
2. 第二部分 寻找key 13在哈希表中显示值为66寻找key 24 不在哈希表中,显示未找到
3. 第三部分 将键值对399修改成3100修改成功显示新值为100将键值对299修改成2100哈希表中不存在键值对299失败.
4. 第四部分 删除键值对3100证明3100消失同时不影响后续结点。
5. 最后释放哈希表占用内存

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -0,0 +1,218 @@
/*
* 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 of hash function and hash test function
* @version: 1
* @author:
* @date: 2023/6/29
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define TABLE_SIZE 10
// 定义哈希表中存储的元素结构
typedef struct Node {
int key;
int value;
struct Node* next;
} Node;
// 定义哈希表结构
typedef struct HashTable {
Node** table; // 存储链表头指针的数组
} HashTable;
// 创建新节点
Node* createNode(int key, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
return newNode;
}
// 初始化哈希表
HashTable* createHashTable() {
HashTable* hashTable = (HashTable*)malloc(sizeof(HashTable));
hashTable->table = (Node**)calloc(TABLE_SIZE, sizeof(Node*));
return hashTable;
}
// 哈希函数,计算键的索引
int hashFunction(int key) {
return key % TABLE_SIZE;
}
// 在哈希表中插入键值对
void insert(HashTable* hashTable, int key, int value) {
int index = hashFunction(key);
Node* newNode = createNode(key, value);
if (hashTable->table[index] == NULL) {
hashTable->table[index] = newNode;
} else {
Node* current = hashTable->table[index];
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
// 在哈希表中查找键是否存在
int find(HashTable* hashTable, int key) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key) {
return 1;
}
current = current->next;
}
return 0; // 未找到对应的值
}
// 在哈希表中查找键对应的值
int get(HashTable* hashTable, int key) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key) {
return current->value;
}
current = current->next;
}
return -1; // 未找到对应的值
}
int change(HashTable* hashTable, int key , int oldValue , int newValue) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
while (current != NULL) {
if (current->key == key && current->value == oldValue) {
current->value = newValue;
return 1;
}
current = current->next;
}
return 0; // 未找到对应的键值对
}
int deleteNode(HashTable* hashTable, int key , int value ) {
int index = hashFunction(key);
Node* current = hashTable->table[index];
Node* last = current;
if(current != NULL){
if (current->key == key && current->value == value){
hashTable->table[index] = current->next;
free(current);
return 1;
}
current = current->next;
}
while (current != NULL) {
if (current->key == key && current->value == value) {
last->next=current->next;
free(current);
return 1;
}
last = current;
current = current->next;
}
return 0; // 未找到对应的键值对
}
void TestHash(void)
{
HashTable* hashTable = createHashTable();
printf("hashmap created\n");
// 在哈希表中插入键值对
insert(hashTable, 3, 99);
printf("key-value pairs 3,99 inserted\n");
insert(hashTable, 7, 88);
printf("key-value pairs 7,88 inserted\n");
insert(hashTable, 13, 66);
printf("key-value pairs 13,66 inserted\n");
insert(hashTable, 17, 55);
printf("key-value pairs 17,55 inserted\n");
printf("\n");
// 查找键对应的值
printf("find key 13 in created hashmap\n");
if(find(hashTable, 13)){
int value = get(hashTable, 13);
printf("Value: %d\n", value); // Output: 66
} else {
printf("key not found\n");
}
printf("find key 24 in created hashmap\n");
if(find(hashTable, 24)){
int value = get(hashTable, 24);
printf("Value: %d\n", value);
} else {
printf("key not found\n");
}
printf("\n");
printf("key-value pairs 3,99 changed to 3,100\n");
if(change(hashTable,3,99,100)){
printf("success!value now: %d\n",get(hashTable,3));
} else {
printf("fail!key-value pairs 3,99 not found\n");
}
printf("key-value pairs 2,99 changed to 2,100\n");
if(change(hashTable,2,99,100)){
printf("success!value: %d\n",get(hashTable,2));
} else {
printf("fail!key-value pairs 2,99 not found\n");
}
printf("\n");
if(deleteNode(hashTable,3,100)){
printf("key-value pairs 3,100 deleted\n");
} else {
printf("key-value pairs 3,100 not found\n");
}
find(hashTable,3) ? printf("key 3 : in hashmap\n") : printf("key 3 : not in hashmap\n");
find(hashTable,13) ? printf("key 13 : in hashmap\n") : printf("key 13 : not in hashmap\n");
printf("\n");
// free hash map
free(hashTable->table);
free(hashTable);
printf("hashmap freed\n");
return;
}
PRIV_SHELL_CMD_FUNCTION(TestHash, a hash test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#endif

View File

@ -20,7 +20,7 @@ extern int FrameworkInit();
extern void ApplicationOtaTaskInit(void);
int main(void)
{
printf("Hello, world! \n");
printf("Hello, world! \n Running on stm32f407-st-discovery\n");
FrameworkInit();
#ifdef APPLICATION_OTA
ApplicationOtaTaskInit();