摘要:衣食住行人们生活中最基础的,随着社会发展,人们的生活水平不断提高,衣服、鞋子更新换代也越来越快,开一个服装店、鞋店感觉是个很好的选择,本课程设计使用哈希表进行鞋店仓库管理系统的模拟,统计一段时间内的进货量、出货量、库存,为鞋店老板提供一些基本服务,实现基本的数据存储和处理操作。
关键词:管理系统;哈希表;数据结构
1、需求分析
1.1问题描述
鞋店仓库管理,系统设计要求:1)能正确的统计进货量、出货量,方便商家了解情况;2)能实时更新数据,让商家根据鞋子数据来确定进货。
1.2模块组成
主程序模块:初始化工作及功能选择和调用
创建模块:要求能新建新的鞋子信息。
删除模块:查找到指定的鞋子,并从系统中删除掉其信息。
查询模块:能够通过鞋子信息查找,迅速的找到要查找的鞋子,并显示其详细信息。
更新模块:在迅速地找到指定鞋子后,对出货量和库存进行更新。
2、概要设计
2.1 设计思路
每一个尺寸的鞋子看作一个基本单位,将系统抽象包括鞋子名字、鞋子的码数、鞋子的进货量、鞋子的出货量和鞋子的库存量等不做存储和处理。为了便于后期维护与找错,使结构更加明了,采用数据结构型函数与功能实现型函数分离结构,存储数据结构是哈希表。
2.2 存储结构设计
数据结构存储采用的是哈希表,本程序通过哈希函数对字符串进行散列,得到一个整数的hash值,根据得到的hash值选择一个槽位置,解决冲突方法为链接法,如图哈希表存储模型。
2.3 算法设计说明
下面将从函数调用关系和对部分算法设计说明两个方面进行
2.3.1 函数调用关系
2.3.2 算法设计说明
哈希表初始化算法思想是,为哈希表主槽申请空间并置为0。
获取哈希值所在哈希表槽位的思想是,通过哈希函数将输入的参数散列成一个整数哈希值。
哈希表插入元素的思想是,先求插入值的主槽,主槽存在该元素则直接更新值域,如果主槽不是该元素,则冲突处理,本程序用链接法,查看主槽冲突指针域,重复上述过程,即找主槽,然后遍历主槽冲突链,存在就更新,不存在就插入。
哈希表删除元素的思想与插入元素的思想较为类似,将对应插入改成删除。
哈希表搜索的思想是,先求要搜索值的哈希值,再利用判断哈希值所在哈希表槽位的算法找到该槽位,对比该槽位元素查看是否一致,一致则查找成功,不一样则看该槽位是否有冲突元素,有的话则对比该槽位元素是否一致,没有的话则不存在该元素,查找失败。
打印全部数据元素个数的思想为,遍历主槽,如果主槽后面有冲突链则遍历冲突链。
3、详细设计
3.1 结构体定义
根据存储结构设计,哈希表结构体的定义为:
//定义数据元素类型
typedef struct shoes
{
char shoesName[20];
int shoesSize;
int shoesRestock;
int shoesSell;
int shoesInventory;
}Shoes;
//定义储存数据元素的链表类型
typedef struct linkNode
{
Shoes shoesMessage;
struct linkNode *pNext;
}ShoesLink;
//定义hash表
typedef struct hash
{
ShoesLink **arr;
int count;
int shoesCount;
}Hash;
3.3 数据结构型函数
3.3.1 初始化函数
根据哈希表初始化思想,初始化函数如下:
//hash函数,通过输入的鞋子名称和码数确定主槽位置
//返回值:要存储数据的下标
int hashFunc(Shoes itemShoes)
{
int sum = 0;
char *p = itemShoes.shoesName;
while('\0' != *p)
{
sum += *p - 'a';
p++;
}
sum = (sum+itemShoes.shoesSize)%P;
if(0 > sum)
{
sum = -1*sum;
}
return sum;
}
3.3.2 哈希表插入元素与删除元素
根据哈希表插入元素与删除元素算法思想,以插入为例代码如下:
//向hash表中插入数据
//参数:hash表首地址 插入的数据
//返回值:成功返回OK,失败返回失败原因
int insertShoes(Hash *pHash,Shoes newShoes)
{
//判断hash表是否存在
if(NULL == pHash)
{
return HASHNOEXIST;
}
//创建新的数据元素节点并放入到hash表中
ShoesLink *pNew = (ShoesLink *)malloc(sizeof(ShoesLink));
if(NULL == pNew)
{
return MALERR;
}
memset(pNew,'\0',sizeof(ShoesLink));
//将要插入的数据放入到新的节点中
pNew->shoesMessage = newShoes;
//查找输入的数据是否存在
if(NULL != searchShoes(pHash,newShoes))
{
return SHOESEXIST;
}
//如果不存在,通过hash函数获取将要存入的位置
int pos = hashFunc(newShoes);
printf("%d\n",pos);
//通过头插法将新节点插入到对应位置
pNew->pNext = pHash->arr[pos];
pHash->arr[pos] = pNew;
pHash->shoesCount++;//统计插入元素个数
return OK;
}
3.3.3 哈希表查找元素
根据哈希表查找元素思想,代码如下:
//在hash表中查找指定数据
//参数:hash表首地址 查找的数据
//返回值:成功返回节点的地址,失败返回NULL
ShoesLink *searchShoes(Hash *pHash,Shoes itemShoes)
{
//判断hash表是否存在
if(NULL == pHash)
{
return NULL;
}
//获取要查找的数据存储的下标
int pos = hashFunc(itemShoes);
ShoesLink *pTmp = pHash->arr[pos];
//遍历链表
while(NULL != pTmp)
{
if(0 == strcmp(pTmp->shoesMessage.shoesName,itemShoes.shoesName) && \
(pTmp->shoesMessage.shoesSize == itemShoes.shoesSize))
{
return pTmp;
}
pTmp = pTmp->pNext;
}
return NULL;
}