This commit is contained in:
ian 2023-06-16 09:58:50 +08:00
parent 7754a149a9
commit d1198dd4d7
10 changed files with 250 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 CONFLICT SAMPLE"
default n
endif
endmenu

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -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=1value=1
![结点](./search.jpg)
4. 删除键key=222value=222的键值对打印并查看删除情况
![结点](./deletion.jpg)
5. 销毁哈希表:
![结点](./destroy.jpg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,157 @@
#include <stdio.h>
#include <string.h>
#include "test_hash.h"
#include <transform.h>
// 哈希函数,根据键值计算哈希值
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);

View File

@ -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