demo
This commit is contained in:
parent
7754a149a9
commit
385a52ab24
|
@ -239,6 +239,10 @@ menu "test app"
|
||||||
menuconfig USER_TEST_TIMER
|
menuconfig USER_TEST_TIMER
|
||||||
bool "Config test soft timer"
|
bool "Config test soft timer"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
menuconfig USER_TEST_HASH
|
||||||
|
bool "Config test hash"
|
||||||
|
default y
|
||||||
|
|
||||||
endif
|
endif
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -100,6 +100,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
ifeq ($(CONFIG_USER_TEST_TIMER),y)
|
ifeq ($(CONFIG_USER_TEST_TIMER),y)
|
||||||
SRC_FILES += test_timer.c
|
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
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||||
|

|
||||||
|
1. 第一部分 插入了四个键值对
|
||||||
|
2. 第二部分 寻找key 13,在哈希表中,显示值为66;寻找key 24, 不在哈希表中,显示未找到
|
||||||
|
3. 第三部分 将键值对3,99修改成3,100,修改成功,显示新值为100;将键值对2,99修改成2,100,哈希表中不存在键值对2,99,失败.
|
||||||
|
4. 第四部分 删除键值对3,100,证明3,100消失,同时不影响后续结点。
|
||||||
|
5. 最后释放哈希表占用内存
|
Binary file not shown.
After Width: | Height: | Size: 128 KiB |
|
@ -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
|
|
@ -20,7 +20,7 @@ extern int FrameworkInit();
|
||||||
extern void ApplicationOtaTaskInit(void);
|
extern void ApplicationOtaTaskInit(void);
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf("Hello, world! \n");
|
printf("Hello, world! \n Running on stm32f407-st-discovery\n");
|
||||||
FrameworkInit();
|
FrameworkInit();
|
||||||
#ifdef APPLICATION_OTA
|
#ifdef APPLICATION_OTA
|
||||||
ApplicationOtaTaskInit();
|
ApplicationOtaTaskInit();
|
||||||
|
|
Loading…
Reference in New Issue