Update README.md
This commit is contained in:
parent
ef2f26253c
commit
131600a5cc
|
@ -1,58 +1,80 @@
|
||||||
# 基于cortex-m3-emulator实现哈希表并测试验证##
|
# ##请填写赛题题目##
|
||||||
|
热身赛一级赛题1:基于cortex-m3-emulator实现哈希表并测试验证
|
||||||
## 1. 简介
|
## 1. 简介
|
||||||
利用c语言实现了哈希表(HashMap),包括添加键值对(Put),获取键对应的值(Get), 删除健(Delete),清空哈希表(Clear), 迭代遍历哈希表(hashMapIterator)等功能
|
|
||||||
操作。
|
|
||||||
|
|
||||||
利用数组(Entry)作为存储空间,利用链表(*next)解决冲突。当哈希表的大小超过数组大小后,为避免发生冲突过多的情况,可以对哈希表扩容。
|
哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方。
|
||||||
|
哈希表(散列表)是直接通过关键字key得到要查找的记录的内存存储位置。
|
||||||
|
散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。
|
||||||
|
采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表或者哈希表。
|
||||||
|
整个散列过程分为两步:
|
||||||
|
1.在存储时,通过散列函数计算记录的散列地址,并按此地址存储该记录。
|
||||||
|
2.当查找记录时,通过同样的散列函数计算记录的散列地址,按此地址方位记录。
|
||||||
|
因此散列技术既是一种存储方法也是一种查找方法,数据元素之间不存在逻辑关系。
|
||||||
|
散列技术最合适的问题是查找与给定值相等的记录。
|
||||||
|
散列函数设计的两个原则是计算简单、散列地址分布均匀。
|
||||||
|
最长用的方法是除留余数法,f(key)=key mod p(p小于等于散列表的长度m)。
|
||||||
|
但散列函数可能会造成冲突,即两个不同的记录求得的散列地址一样,解决散列冲突最常用的方法为开放定址法。一旦发生冲突,就去寻找下一个散列地址,只要散列表足够大,空的散列地址总能找到。
|
||||||
|
|
||||||
## 2. 数据结构设计说明
|
## 2. 数据结构设计说明
|
||||||
键值对结构
|
|
||||||
typedef struct entry {
|
|
||||||
void * key; // 键
|
|
||||||
void * value; // 值
|
|
||||||
struct entry * next; // 冲突链表
|
|
||||||
}*Entry;
|
|
||||||
|
|
||||||
哈希结构
|
typedef struct
|
||||||
typedef struct hashMap {
|
{
|
||||||
int size; // 当前大小
|
int *elem;
|
||||||
int listSize; // 有效空间大小
|
int count;
|
||||||
HashCode hashCode; // 哈希函数
|
}HashTable;
|
||||||
Equal equal; // 判等函数
|
int m=0;
|
||||||
Entry list; // 存储区域
|
|
||||||
Put put; // 添加键的函数
|
|
||||||
Get get; // 获取键对应值的函数
|
|
||||||
Remove remove; // 删除键
|
|
||||||
Clear clear; // 清空Map
|
|
||||||
Exists exists; // 判断键是否存在
|
|
||||||
Boolean autoAssign; // 设定是否根据当前数据量动态调整内存大小,默认开启
|
|
||||||
}*HashMap;
|
|
||||||
|
|
||||||
包括以下函数功能,分别为:
|
//初始化散列表
|
||||||
`createHashMap`:创建一个哈希结构
|
int InitHashTable(HashTable *H)
|
||||||
`defaultPut`:添加键值对
|
{
|
||||||
`defaultGet`:获取键对应值
|
int i;
|
||||||
`defaultRemove`:删除指定键的键值对
|
m=HASHSIZE;
|
||||||
`defaultExists`:判断键值是否存在
|
H->count=m;
|
||||||
`defaultClear`:清空Map的函数类型
|
H->elem=(int*)malloc(m*sizeof(int));
|
||||||
`resetHashMap`:重新构建哈希表
|
for(i=0;i<m;i++)
|
||||||
|
H->elem[i]=NULLKEY;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//散列函数
|
||||||
|
int Hash(int key)
|
||||||
|
{
|
||||||
|
return key%m;
|
||||||
|
}
|
||||||
|
//插入关键字进入散列表
|
||||||
|
void InsertHash(HashTable *H,int key)
|
||||||
|
{
|
||||||
|
int addr=Hash(key);
|
||||||
|
while(H->elem[addr]!=NULLKEY)
|
||||||
|
addr=(addr+1)%m;
|
||||||
|
H->elem[addr]=key;
|
||||||
|
}
|
||||||
|
|
||||||
|
//散列表查找关键字
|
||||||
|
int SearchHash(HashTable H,int key,int *addr)
|
||||||
|
{
|
||||||
|
*addr=Hash(key);
|
||||||
|
while(H.elem[*addr]!=key)
|
||||||
|
{
|
||||||
|
*addr=(*addr+1)%m;
|
||||||
|
if(H.elem[*addr]==NULLKEY||*addr==Hash(key))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
## 3. 测试程序说明
|
## 3. 测试程序说明
|
||||||
测试了哈希表的插入键值对(Put),判断键是否存在(Exist),获取键对应的值(Get), 删除健(Delete),迭代遍历哈希表(hashMapIterator),清空哈希表(Clear)等操作。
|
|
||||||
并展示了利用链地址法解决哈希冲突的示例, 两个不同的人(Bob和Li Ming)的hashcode相同。
|
1.安装qemu
|
||||||
|
sudo apt install qemu-system-arm
|
||||||
|
2.通过以下命令启动QEMU并加载XiUOS ELF文件
|
||||||
|
qemu-system-arm -machine lm3s6965evb -nographic -kernel build/XiZi-cortex-m3-emulator.elf
|
||||||
|
|
||||||
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||||

|
配置文件并编译,在终端中执行的命令行效果如下图
|
||||||
打开menuconfig之后,将test_hash_map开启(y),保存后退出
|
![Image test]https://www.gitlink.org.cn/Mao1223/xiuos/tree/2023_open_source_contest/image-1.png)
|
||||||
|
在qemu上运行命令行效果如下图
|
||||||

|

|
||||||
编译XiZi-cortex-m3-emulator.elf成功
|
可见实现了在qemu上实现哈希表,用链地址法解决哈希冲突。
|
||||||
|
|
||||||

|
|
||||||
启动qemu模拟Xiuos操作系统,验证TestHash注册Shell命令
|
|
||||||
|
|
||||||

|
|
||||||
执行TestHash命令,打印测试结果。
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue