oscar 2023_open_source_contest_warmup_1st_issue1
This commit is contained in:
parent
7754a149a9
commit
020b342e3b
|
@ -0,0 +1,37 @@
|
|||
# ##2023_open_source_contest_warmup_1st_issue1##
|
||||
|
||||
## 1. 简介
|
||||
基于矽璓模拟器cortex-m3-emulator,实现哈希表,支持链地址法解决哈希冲突,并编写测试程序在shell终端打印结果。
|
||||
经过测试,我们的代码完美实现了热身赛赛题1所规定的全部预期功能。
|
||||
|
||||
|
||||
## 2. 数据结构设计说明
|
||||
源代码文件test_hash.c中,实现了一个基于哈希表的键值对存储结构,并提供了一系列操作该数据结构的函数。主要功能包括:
|
||||
1. `InitHashTable()`:初始化一个哈希表,返回一个指向 `HashTableType` 类型的指针。
|
||||
2. `GetHash(int key)`:给定一个键值,计算其哈希值并返回。
|
||||
3. `InitNode(int key, int value)`:初始化一个节点,返回一个指向 `NodeType` 类型的指针。
|
||||
4. `GetTableSize(HashTableType* hash_table)`:获取哈希表中键值对的数量。
|
||||
5. `FindNode(HashTableType* hash_table, int key)`:在哈希表中查找指定键值的节点,如果存在则返回该节点的指针,否则返回 `NULL`。
|
||||
6. `InsertNode(HashTableType* hash_table, int key, int value)`:向哈希表中插入一个键值对,如果插入成功则返回 1,否则返回 0。
|
||||
7. `RemoveNode(HashTableType* hash_table, int key)`:从哈希表中删除指定键值的节点,如果删除成功则返回 1,否则返回 0。
|
||||
8. `ModifyNode(HashTableType* hash_table, int key, int value)`:修改哈希表中指定键值的节点的值,如果修改成功则返回 1,否则返回 0。
|
||||
9. `Display(HashTableType* hash_table)`:打印哈希表中所有的键值对。
|
||||
10. `TestHash()`:对哈希表进行一系列测试,包括插入、查找、修改、删除等操作,并输出相应的结果。
|
||||
此程序文件与其他模块或函数的接口关系较少,主要使用了自定义的数据结构类型 `HashTableType` 和 `NodeType`,以及一些标准库函数(如 `malloc` 和 `printf`)。输出值的含义和取值范围在函数中有相应的注释和说明。参数间的控制、顺序、独立或依赖等关系主要由函数的实现决定,例如删除节点前需要先查找节点,修改节点前需要先判断节点是否存在等。函数之间相互独立,可以单独调用,但也可以组合使用。
|
||||
头文件test_hash.h中定义了一个基于链表的哈希表数据结构。其中:
|
||||
1. `NodeType` 结构体表示哈希表中的一个节点,包含了该节点的键值以及指向下一个节点的指针。
|
||||
2. `HashTableType` 结构体表示整个哈希表,包含了一个长度为 `MAX_TABLE_SIZE` 的指针数组 `table`,用于存储节点,并且记录了哈希表中节点的数量 `tabel_size`。
|
||||
该头文件的主要功能是定义了 `NodeType` 和 `HashTableType` 两个自定义的数据类型,为使用基于链表的哈希表提供了便利。可以在需要使用哈希表的代码中包含该头文件,并根据需要创建相应的 `HashTableType` 变量,然后使用其中定义的函数来操作哈希表。例如可以使用 `InitHashTable()` 函数来初始化哈希表,使用 `InsertNode()` 函数来插入一个节点,使用 `FindNode()` 函数来查找指定键值的节点等等。具体使用方法可以参考使用哈希表的代码示例.
|
||||
|
||||
|
||||
## 3. 测试程序说明
|
||||
测试函数为InsertNode、Display、FindNode、ModifyNode、RemoveNode。首先新增节点,之后展示,再测试查找操作、修改节点、移除节点等操作。
|
||||
|
||||
|
||||
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||
打开menuconfig进行裁剪
|
||||

|
||||
编译项目
|
||||

|
||||
启动qemu并且运行Shell命令
|
||||

|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (c) 2023 oscar
|
||||
* 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 name: tesh_hash.c// 文件名
|
||||
Description: 这段代码实现了一个基于哈希表的键值对存储结构,并提供了一系列操作该数据结构的函数。主要功能包括:
|
||||
1. `InitHashTable()`:初始化一个哈希表,返回一个指向 `HashTableType` 类型的指针。
|
||||
2. `GetHash(int key)`:给定一个键值,计算其哈希值并返回。
|
||||
3. `InitNode(int key, int value)`:初始化一个节点,返回一个指向 `NodeType` 类型的指针。
|
||||
4. `GetTableSize(HashTableType* hash_table)`:获取哈希表中键值对的数量。
|
||||
5. `FindNode(HashTableType* hash_table, int key)`:在哈希表中查找指定键值的节点,如果存在则返回该节点的指针,否则返回 `NULL`。
|
||||
6. `InsertNode(HashTableType* hash_table, int key, int value)`:向哈希表中插入一个键值对,如果插入成功则返回 1,否则返回 0。
|
||||
7. `RemoveNode(HashTableType* hash_table, int key)`:从哈希表中删除指定键值的节点,如果删除成功则返回 1,否则返回 0。
|
||||
8. `ModifyNode(HashTableType* hash_table, int key, int value)`:修改哈希表中指定键值的节点的值,如果修改成功则返回 1,否则返回 0。
|
||||
9. `Display(HashTableType* hash_table)`:打印哈希表中所有的键值对。
|
||||
10. `TestHash()`:对哈希表进行一系列测试,包括插入、查找、修改、删除等操作,并输出相应的结果。
|
||||
此程序文件与其他模块或函数的接口关系较少,主要使用了自定义的数据结构类型 `HashTableType` 和 `NodeType`,以及一些标准库函数(如 `malloc` 和 `printf`)。输出值的含义和取值范围在函数中有相应的注释和说明。参数间的控制、顺序、独立或依赖等关系主要由函数的实现决定,例如删除节点前需要先查找节点,修改节点前需要先判断节点是否存在等。函数之间相互独立,可以单独调用,但也可以组合使用。// ⽤于详细说明此程序文件完成的主要功能,与其他模块或函数的接⼝,输出值、取值范围、含义及参数间的控制、顺序、独立或依赖等关系
|
||||
Others: V1.0// 其它内容的说明
|
||||
History: // 修改历史记录列表,每条修改记录应包括修改⽇期、修改者及修改内容简述
|
||||
1. Date: 2023.7.2
|
||||
Author: oscar
|
||||
Modification: Achieve the intended function. Add and normalize comments.
|
||||
*************************************************/
|
||||
|
||||
#include <transform.h>
|
||||
#include "test_hash.h"
|
||||
|
||||
HashTableType* InitHashTable() {
|
||||
HashTableType* hash_table = (HashTableType*)malloc(sizeof(HashTableType));
|
||||
hash_table->tabel_size = 0;
|
||||
for (int i = 0; i < MAX_TABLE_SIZE; i++)
|
||||
hash_table->table[i] = NULL;
|
||||
return hash_table;
|
||||
}
|
||||
|
||||
int GetHash(int key) {
|
||||
return key % MAX_TABLE_SIZE;
|
||||
}
|
||||
|
||||
NodeType* InitNode(int key, int value) {
|
||||
NodeType* node = (NodeType*)malloc(sizeof(NodeType));
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->next = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
int GetTableSize(HashTableType* hash_table) {
|
||||
return hash_table->tabel_size;
|
||||
}
|
||||
|
||||
NodeType* FindNode(HashTableType* hash_table, int key) {
|
||||
int index = GetHash(key);
|
||||
NodeType* nowNode = hash_table->table[index];
|
||||
while (nowNode != NULL) {
|
||||
if (nowNode->key == key) {
|
||||
return nowNode;
|
||||
}
|
||||
nowNode = nowNode->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InsertNode(HashTableType* hash_table, int key, int value) {
|
||||
if (GetTableSize(hash_table) >= MAX_TABLE_SIZE) {
|
||||
printf("Fail to insert, HashTableType is full.");
|
||||
return;
|
||||
}
|
||||
|
||||
int index = GetHash(key);
|
||||
if (hash_table->table[index] == NULL) {
|
||||
NodeType* InsertNode = InitNode(key, value);
|
||||
hash_table->table[index] = InsertNode;
|
||||
hash_table->tabel_size++;
|
||||
} else {
|
||||
NodeType* nowNode = hash_table->table[index];
|
||||
while (nowNode->next != NULL && nowNode->key != key)
|
||||
nowNode = nowNode->next;
|
||||
if (nowNode->key == key) {
|
||||
nowNode->value = value;
|
||||
} else {
|
||||
NodeType* InsertNode = InitNode(key, value);
|
||||
nowNode->next = InsertNode;
|
||||
hash_table->tabel_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RemoveNode(HashTableType* hash_table, int key) {
|
||||
int index = GetHash(key);
|
||||
NodeType* nowNode = hash_table->table[index];
|
||||
NodeType* preNode = NULL;
|
||||
|
||||
while (nowNode != NULL) {
|
||||
if (nowNode->key == key) {
|
||||
if (preNode == NULL) {
|
||||
hash_table->table[index] = nowNode->next;
|
||||
} else {
|
||||
preNode->next = nowNode->next;
|
||||
}
|
||||
free(nowNode);
|
||||
hash_table->tabel_size--;
|
||||
return 1;
|
||||
}
|
||||
preNode = nowNode;
|
||||
nowNode = nowNode->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ModifyNode(HashTableType* hash_table, int key, int value) {
|
||||
if (FindNode(hash_table,key) == 0)
|
||||
return 0;
|
||||
int index = GetHash(key);
|
||||
NodeType* nowNode = hash_table->table[index];
|
||||
while (nowNode != NULL) {
|
||||
if (nowNode->key == key) {
|
||||
nowNode->value = value;
|
||||
return 1;
|
||||
}
|
||||
nowNode = nowNode->next;
|
||||
}
|
||||
}
|
||||
|
||||
void Display(HashTableType* hash_table) {
|
||||
printf("HashTableType:{");
|
||||
for (int i = 0; i < MAX_TABLE_SIZE; i++) {
|
||||
NodeType* nowNode = hash_table->table[i];
|
||||
while (nowNode != NULL) {
|
||||
printf("(%d, %d),", nowNode->key, nowNode->value);
|
||||
nowNode = nowNode->next;
|
||||
}
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
void TestHash() {
|
||||
HashTableType* hash_table = InitHashTable();
|
||||
|
||||
//测试增加
|
||||
printf("testing add method...\n");
|
||||
printf("Add 3 node to hashtable....\n");
|
||||
InsertNode(hash_table,2,2);
|
||||
Display(hash_table);
|
||||
InsertNode(hash_table,3,3);
|
||||
Display(hash_table);
|
||||
InsertNode(hash_table,4,4);
|
||||
Display(hash_table);
|
||||
|
||||
//测试哈希表满
|
||||
printf("\nHashTable maxsize is 3, now insert 4th node, check if success:\n ");
|
||||
InsertNode(hash_table,14,14);
|
||||
|
||||
//测试查找
|
||||
printf("\ntesting find method...\n");
|
||||
NodeType* found_node = FindNode(hash_table,4);
|
||||
printf("find key 4,value is %d\n",found_node->value);
|
||||
|
||||
//测试修改
|
||||
printf("\ntesting modify method...\n");
|
||||
printf("modify key=2 value=100\n");
|
||||
int check_success = ModifyNode(hash_table, 2, 100);
|
||||
if(check_success == 0) {
|
||||
printf("modify failed, key not exist.\n");
|
||||
} else{
|
||||
printf("modify success\n");
|
||||
}
|
||||
found_node = FindNode(hash_table, 2);
|
||||
printf("verify: (%d %d)\n", found_node->key, found_node->value);
|
||||
|
||||
Display(hash_table);
|
||||
|
||||
// 删除键值对
|
||||
printf("\ntesting remove method...\n");
|
||||
check_success = RemoveNode(hash_table, 3);
|
||||
if (check_success == 0) {
|
||||
printf("key not exist, fail to remove.\n");
|
||||
} else {
|
||||
printf("remove success\n");
|
||||
}
|
||||
found_node = FindNode(hash_table,3);
|
||||
if (found_node == NULL) {
|
||||
printf("verify: key 3 is removed\n");
|
||||
}
|
||||
|
||||
Display(hash_table);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestHash, Implement a simple printf test, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2023 oscar
|
||||
* 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 name: tesh_hash.h// 文件名
|
||||
Description: 这个头文件定义了一个基于链表的哈希表数据结构。其中:
|
||||
1. `NodeType` 结构体表示哈希表中的一个节点,包含了该节点的键值以及指向下一个节点的指针。
|
||||
2. `HashTableType` 结构体表示整个哈希表,包含了一个长度为 `MAX_TABLE_SIZE` 的指针数组 `table`,用于存储节点,并且记录了哈希表中节点的数量 `tabel_size`。
|
||||
该头文件的主要功能是定义了 `NodeType` 和 `HashTableType` 两个自定义的数据类型,为使用基于链表的哈希表提供了便利。可以在需要使用哈希表的代码中包含该头文件,并根据需要创建相应的 `HashTableType` 变量,然后使用其中定义的函数来操作哈希表。例如可以使用 `InitHashTable()` 函数来初始化哈希表,使用 `InsertNode()` 函数来插入一个节点,使用 `FindNode()` 函数来查找指定键值的节点等等。具体使用方法可以参考使用哈希表的代码示例.// ⽤于详细说明此程序文件完成的主要功能,与其他模块或函数的接⼝,输出值、取值范围、含义及参数间的控制、顺序、独立或依赖等关系
|
||||
Others: V1.0// 其它内容的说明
|
||||
History: // 修改历史记录列表,每条修改记录应包括修改⽇期、修改者及修改内容简述
|
||||
1. Date: 2023.7.2
|
||||
Author: oscar
|
||||
Modification: Achieve the intended function. Add and normalize comments.
|
||||
*************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_TABLE_SIZE 3
|
||||
|
||||
typedef struct TableNode {
|
||||
int key;
|
||||
int value;
|
||||
struct TableNode* next;
|
||||
} NodeType;
|
||||
|
||||
typedef struct HashTable{
|
||||
NodeType* table[MAX_TABLE_SIZE];
|
||||
int tabel_size;
|
||||
}HashTableType;
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue