一级赛题1
This commit is contained in:
parent
7754a149a9
commit
780999cfe8
|
@ -240,5 +240,8 @@ menu "test app"
|
||||||
bool "Config test soft timer"
|
bool "Config test soft timer"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
menuconfig USER_TEST_HASH
|
||||||
|
bool "Config test hash"
|
||||||
|
default n
|
||||||
endif
|
endif
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -101,5 +101,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),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,184 @@
|
||||||
|
# 热身赛一级赛题1:基于cortex-m3-emulator实现哈希表并测试验证
|
||||||
|
|
||||||
|
## 1. 简介
|
||||||
|
|
||||||
|
用c语言实现哈希表数据结构,编译到cortex-m3-emulator的指令中,并且成功运行。
|
||||||
|
|
||||||
|
## 2. 数据结构设计说明
|
||||||
|
|
||||||
|
```c
|
||||||
|
//定义链表节点结构
|
||||||
|
typedef struct Node {
|
||||||
|
int key;
|
||||||
|
int value;
|
||||||
|
struct Node* next;
|
||||||
|
} Node;
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//哈希表结构
|
||||||
|
typedef struct HashTable {
|
||||||
|
Node* table[TABLE_SIZE];
|
||||||
|
} HashTable;
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//创建新节点的函数,开辟一块内存空间,将key和value赋值并返回
|
||||||
|
Node* createNode(int key, int value) {
|
||||||
|
Node* newNode = (Node*)malloc(sizeof(Node));
|
||||||
|
newNode->key = key;
|
||||||
|
newNode->value = value;
|
||||||
|
newNode->next = NULL;
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//创建哈希表的函数,并为每个节点初始化
|
||||||
|
HashTable* createHashTable() {
|
||||||
|
HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
newTable->table[i] = NULL;
|
||||||
|
}
|
||||||
|
return newTable;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//hash函数,这里简单地把key模TABLE_SIZE的值当做下标
|
||||||
|
int hash(int key) {
|
||||||
|
return key % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//在哈希表中插入键值对的函数
|
||||||
|
void insert(HashTable* ht, int key, int value) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* newNode = createNode(key, value);
|
||||||
|
|
||||||
|
// 如果该位置为空,则直接插入节点
|
||||||
|
if (ht->table[index] == NULL) {
|
||||||
|
ht->table[index] = newNode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 如果该位置已经有节点存在,则将新节点插入链表头部
|
||||||
|
newNode->next = ht->table[index];
|
||||||
|
ht->table[index] = newNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 根据键查找值
|
||||||
|
int search(HashTable* ht, int key) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* currentNode = ht->table[index];
|
||||||
|
|
||||||
|
// 在链表中查找键
|
||||||
|
while (currentNode != NULL) {
|
||||||
|
if (currentNode->key == key) {
|
||||||
|
return currentNode->value;
|
||||||
|
}
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 键未找到
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 从哈希表中删除键值对
|
||||||
|
void delete (HashTable* ht, int key) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* currentNode = ht->table[index];
|
||||||
|
Node* prevNode = NULL;
|
||||||
|
|
||||||
|
// 在链表中查找键
|
||||||
|
while (currentNode != NULL && currentNode->key != key) {
|
||||||
|
prevNode = currentNode;
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果找到键,则删除节点
|
||||||
|
if (currentNode != NULL) {
|
||||||
|
if (prevNode == NULL) {
|
||||||
|
ht->table[index] = currentNode->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prevNode->next = currentNode->next;
|
||||||
|
}
|
||||||
|
free(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 打印哈希表内容
|
||||||
|
void printHashTable(HashTable* ht) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
printf("Bucket %d: ", i);
|
||||||
|
Node* currentNode = ht->table[i];
|
||||||
|
while (currentNode != NULL) {
|
||||||
|
printf("(%d, %d) ", currentNode->key, currentNode->value);
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 测试程序说明
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 测试函数
|
||||||
|
void TestHash(void) {
|
||||||
|
HashTable* ht = createHashTable();
|
||||||
|
|
||||||
|
// 在哈希表中插入键值对
|
||||||
|
insert(ht, 1, 10);
|
||||||
|
insert(ht, 2, 20);
|
||||||
|
insert(ht, 3, 30);
|
||||||
|
insert(ht, 11, 110);
|
||||||
|
insert(ht, 21, 210);
|
||||||
|
insert(ht, 4, 40);
|
||||||
|
|
||||||
|
// 打印哈希表内容
|
||||||
|
printHashTable(ht);
|
||||||
|
|
||||||
|
// 根据键查找值
|
||||||
|
int value = search(ht, 2);
|
||||||
|
printf("Value for key 2: %d\n", value);
|
||||||
|
|
||||||
|
// 从哈希表中删除键值对
|
||||||
|
delete (ht, 3);
|
||||||
|
delete (ht, 11);
|
||||||
|
|
||||||
|
// 打印哈希表内容
|
||||||
|
printHashTable(ht);
|
||||||
|
|
||||||
|
// 释放哈希表内存
|
||||||
|
free(ht);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||||
|
|
||||||
|
成功编译以后在XiZi_IIoT目录下输入指令打开qemu
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
输入Help指令,看到TestHash已经被成功编译为qemu指令
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
输入TestHash,输出结果如下,哈希表的各表项按照指令插入、查询和删除,hash表实现完毕。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* @version: 1.1
|
||||||
|
* @author: ROGEEK TEAM
|
||||||
|
* @date: 2023/6/20
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <transform.h>
|
||||||
|
#include "test_hash.h"
|
||||||
|
#ifdef ADD_XIZI_FETURES
|
||||||
|
// 测试函数
|
||||||
|
void TestHash(void) {
|
||||||
|
HashTable* ht = createHashTable();
|
||||||
|
|
||||||
|
// 在哈希表中插入键值对
|
||||||
|
insert(ht, 1, 10);
|
||||||
|
insert(ht, 2, 20);
|
||||||
|
insert(ht, 3, 30);
|
||||||
|
insert(ht, 11, 110);
|
||||||
|
insert(ht, 21, 210);
|
||||||
|
insert(ht, 4, 40);
|
||||||
|
|
||||||
|
// 打印哈希表内容
|
||||||
|
printHashTable(ht);
|
||||||
|
|
||||||
|
// 根据键查找值
|
||||||
|
int value = search(ht, 2);
|
||||||
|
printf("Value for key 2: %d\n", value);
|
||||||
|
|
||||||
|
// 从哈希表中删除键值对
|
||||||
|
delete (ht, 3);
|
||||||
|
delete (ht, 11);
|
||||||
|
|
||||||
|
// 打印哈希表内容
|
||||||
|
printHashTable(ht);
|
||||||
|
|
||||||
|
// 释放哈希表内存
|
||||||
|
free(ht);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(TestHash, a dac test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||||
|
#endif
|
|
@ -0,0 +1,108 @@
|
||||||
|
#define TABLE_SIZE 10
|
||||||
|
|
||||||
|
// 链表节点结构
|
||||||
|
typedef struct Node {
|
||||||
|
int key;
|
||||||
|
int value;
|
||||||
|
struct Node* next;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
// 哈希表结构
|
||||||
|
typedef struct HashTable {
|
||||||
|
Node* table[TABLE_SIZE];
|
||||||
|
} 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* newTable = (HashTable*)malloc(sizeof(HashTable));
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
newTable->table[i] = NULL;
|
||||||
|
}
|
||||||
|
return newTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 哈希函数
|
||||||
|
int hash(int key) {
|
||||||
|
return key % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在哈希表中插入键值对
|
||||||
|
void insert(HashTable* ht, int key, int value) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* newNode = createNode(key, value);
|
||||||
|
|
||||||
|
// 如果该位置为空,则直接插入节点
|
||||||
|
if (ht->table[index] == NULL) {
|
||||||
|
ht->table[index] = newNode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 如果该位置已经有节点存在,则将新节点插入链表头部
|
||||||
|
newNode->next = ht->table[index];
|
||||||
|
ht->table[index] = newNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据键查找值
|
||||||
|
int search(HashTable* ht, int key) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* currentNode = ht->table[index];
|
||||||
|
|
||||||
|
// 在链表中查找键
|
||||||
|
while (currentNode != NULL) {
|
||||||
|
if (currentNode->key == key) {
|
||||||
|
return currentNode->value;
|
||||||
|
}
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 键未找到
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从哈希表中删除键值对
|
||||||
|
void delete (HashTable* ht, int key) {
|
||||||
|
int index = hash(key);
|
||||||
|
Node* currentNode = ht->table[index];
|
||||||
|
Node* prevNode = NULL;
|
||||||
|
|
||||||
|
// 在链表中查找键
|
||||||
|
while (currentNode != NULL && currentNode->key != key) {
|
||||||
|
prevNode = currentNode;
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果找到键,则删除节点
|
||||||
|
if (currentNode != NULL) {
|
||||||
|
if (prevNode == NULL) {
|
||||||
|
ht->table[index] = currentNode->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prevNode->next = currentNode->next;
|
||||||
|
}
|
||||||
|
free(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印哈希表内容
|
||||||
|
void printHashTable(HashTable* ht) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
printf("Bucket %d: ", i);
|
||||||
|
Node* currentNode = ht->table[i];
|
||||||
|
while (currentNode != NULL) {
|
||||||
|
printf("(%d, %d) ", currentNode->key, currentNode->value);
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue