基于Hash表存储的城市公交管理系统
项目介绍
城市公交的主要属性
在头文件中hash.h
typedef struct time
{
char start[S];
char finish[S];
}Time;
//定义数据
typedef struct bus_data
{
char bus_id[I];//公交编号
char bus_number[S];//公交车车牌号
char bus_driver[N];//司机姓名
char bus_place[N][M];//公交车途径站信息
Time bus_time;//运营时间
}busData;
实现功能介绍
- 插入
- 通过编号查信息
- 根据编号修改信息
- 显示所有信息
- 根据编号删除信息
- 写入到文件
- 从文件中读取
- 销毁空间
目录结构
Makefile
Makefile
ALL:
make -C src
make -C obj
.PHONY:clean
clean:
rm obj/*.o
rm bin/wly
obj/Makefile
../bin/wly:hash.o test.o menu.o
gcc $^ -o $@
src/Makefile
ALL:../obj/test.o ../obj/hash.o ../obj/menu.o
../obj/test.o:test.c
gcc -c -g $< -o $@
../obj/hash.o:hash.c
gcc -c -g $< -o $@
../obj/menu.o:menu.c
gcc -c -g $< -o $@
功能实现
头文件——hash.h
#ifndef _HASH_H
#define _HASH_H
#define I 5
#define S 10
#define M 15
#define N 20
//节点为空
enum res
{
LINKNOEXIST=-3,
MALERR,
FAIL,
OK
};
typedef struct time
{
char start[S];
char finish[S];
}Time;
//定义数据
typedef struct bus_data
{
char bus_id[I];//公交编号
char bus_number[S];//公交车车牌号
char bus_driver[N];//司机姓名
char bus_place[N][M];//公交车途径站信息
Time bus_time;//运营时间
}busData;
//定义节点
typedef struct linknode
{
//数据域
busData data;
//指针域,下一个节点首地址
struct linknode * next;
}LinkNode;
//定义Hash---->数组
typedef struct hash
{
//Hash的地址
LinkNode ** parr;
int size;
}Hash;
//创建hash表
Hash * createHash(int size);
//插入节点
//参数1:Hash表的地址
//参数2:插入的数据
int insertHash(Hash * pHash,busData item);
//搜索Hash表
LinkNode * searchHash(Hash * pHash,busData item);
//根据编号修改信息
int updataHash(Hash * pHash,busData item);
//显示所有信息
int showHash(Hash * pHash,int size);
//根据编号删除信息
int deleteHash(Hash * pHash,busData item);
//写入到文件
void saveFile(Hash * pHash,const char *file);
//从文件中读取
int readFile(Hash * pHash,const char *file);
//销毁
int destoryLink(Hash ** pHash);
int hashFun(busData item);
//菜单
void menu();
#endif
功能实现——hash.c
#include <stdio.h>
#include "../include/hash.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//创建Hash表
Hash * createHash(int size)
{
//结构体分配空间
Hash * pHash=NULL;
pHash=(Hash *)malloc(sizeof(Hash));
//判断空间是否分配成功
if(pHash == NULL)
{
perror("malloc error");
return NULL;
}
//重置空间,首地址,值,大小
memset(pHash,0,sizeof(Hash));
//创建节点空间
pHash->parr=(LinkNode **)malloc(size*sizeof(LinkNode *));
memset(pHash->parr,'\0',sizeof(pHash->parr));
pHash->size=size;
return pHash;
}
//Hash规则 0-----9
int hashFun(busData item)
{
int key;
key=(int)item.bus_id[0];
return key%9;
}
//插入Hash表
//Hash的地址
//busData data数据
int insertHash(Hash * pHash,busData item)
{
//单个节点地址
LinkNode * pNew=NULL;
//创建节点空间
pNew=(LinkNode *)malloc(sizeof(LinkNode));
//判断表是否存在
if(pHash == NULL)
{
return LINKNOEXIST;
}
//判断节点是否创建成功
if(pNew == NULL)
{
perror("malloc error");
return MALERR;
}
//数据入节点
pNew->data=item;
//节点地址入Hash
//hash表中的地址
//根据位置插入---头插
int pos=hashFun(item);
pNew->next=pHash->parr[pos];
pHash->parr[pos]=pNew;
return OK;
}
//通过编号查信息
LinkNode * searchHash(Hash * pHash,busData item)
{
int pos=hashFun(item);
LinkNode * pTmp=pHash->parr[pos];
while(pTmp != NULL)
{
if(strcmp(pTmp->data.bus_id,item.bus_id)==0)
{
return pTmp;
}
pTmp=pTmp->next;
}
return NULL;
}
//根据编号修改信息
int updataHash(Hash * pHash,busData item)
{
int pos=hashFun(item);
LinkNode * pTmp=pHash->parr[pos];
while(pTmp != NULL)
{
if(strcmp(pTmp->data.bus_id,item.bus_id)==0)
{
strcpy(pTmp->data.bus_driver,item.bus_driver);
return OK;
}
pTmp=pTmp->next;
}
return FAIL;
}
//显示所有信息
int showHash(Hash * pHash,int size)
{
int i=0;
if(pHash==NULL) return LINKNOEXIST;
for(i=0;i<size;i++)
{
LinkNode * pTmp=pHash->parr[i];
while(pTmp != NULL)
{
printf("公交编号:%s\n公交车车牌号:%s\n司机姓名:%s\n",pTmp->data.bus_id,pTmp->data.bus_number,pTmp->data.bus_driver);
printf("公交车途径站信息:");
int j=0;
while(1)
{
printf("%s",pTmp->data.bus_place[j]);
if(strcmp(pTmp->data.bus_place[j],"over")==0) break;
printf("->->->");
j++;
}
printf("\n公交车运营时间:");
printf(" %s---%s\n",pTmp->data.bus_time.start,pTmp->data.bus_time.finish);
pTmp=pTmp->next;
printf("———————————————————————————————————————————————————————\n");
}
}
return OK;
}
//根据编号删除信息
int deleteHash(Hash * pHash,busData item)
{
int i=0;
int pos=hashFun(item);
LinkNode * pTmp=pHash->parr[pos];
LinkNode * pLast;
while(pTmp != NULL)
{
if(strcmp(pTmp->data.bus_id,item.bus_id)==0)
{
if(i==0)
{
pHash->parr[pos]=pTmp->next;
}
else
{
pLast->next=pTmp->next;
}
printf("删除成功\n");
return OK;
}
pLast=pTmp;
pTmp=pTmp->next;
i++;
}
return LINKNOEXIST;
}
//保存到文件
void saveFile(Hash * pHash,const char * file)
{
int fw=0;
fw=open(file,O_WRONLY|O_CREAT|O_APPEND,0777);
for(int i=0;i<10;i++)
{
LinkNode * pTmp=pHash->parr[i];
while(pTmp != NULL)
{
write(fw,pTmp,sizeof(LinkNode));
pTmp=pTmp->next;
}
}
close(fw);
printf("保存成功\n");
}
//从文件中读取
int readFile(Hash * pHash,const char *file)
{
int fr=0;
//单个节点地址
fr=open(file,O_RDONLY);
if(fr==-1)
{
perror("open error");
return FAIL;
}
LinkNode * pNew=NULL;
//创建节点空间
pNew=(LinkNode *)malloc(sizeof(LinkNode));
while(1)
{
int op=read(fr,pNew,sizeof(LinkNode));
if(op == 0) break;
insertHash(pHash,pNew->data);
}
close(fr);
return OK;
}
//销毁
int destoryLink(Hash ** pHash)
{
int i=0;
if(*pHash == NULL)return MALERR;
for(i=0;i<10;i++)
{
LinkNode * pTmp=(*pHash)->parr[i];
while(1)
{
if(pTmp == NULL) break;
deleteHash(*pHash,pTmp->data);
pTmp=pTmp->next;
}
free(pTmp);
pTmp=NULL;
}
free((*pHash)->parr);
free(*pHash);
*pHash=NULL;
return OK;
}
菜单——menu.c
#include <stdio.h>
void menu()
{
printf("1----------插入\n");
printf("2----------通过编号查信息\n");
printf("3----------根据编号修改信息\n");
printf("4----------显示所有信息\n");
printf("5----------根据编号删除信息\n");
printf("6----------写入到文件\n");
printf("7----------从文件中读取\n");
printf("8----------销毁空间\n");
printf("-1----------exit\n");
}
测试——test.c
#include <stdio.h>
#include "../include/hash.h"
#include <string.h>
int main()
{
Hash * pHash=NULL;
char str[10]="over";
busData item;
int op=0;
char file[10];
LinkNode * pTmp=NULL;
//创建链表
pHash=createHash(S);
//根据菜单选择操作
while(1)
{
menu();
printf("请输入选项:\n");
scanf("%d",&op);
if(op == -1)break;
switch(op)
{
case 1:
//插入
printf("请输入你要插入的公交编号:\n");
scanf("%s",item.bus_id);
printf("请输入你要插入的公交车车牌号:\n");
scanf("%s",item.bus_number);
printf("请输入你要插入的司机姓名:\n");
scanf("%s",item.bus_driver);
printf("请输入你要插入的公交车途径站信息以“over”结束:\n");
int i=0;
while(1)
{
scanf("%s",item.bus_place[i]);
if(strcmp(item.bus_place[i],"over")==0) break;
i++;
}
printf("请输入你要插入的公交车运营时间(起始时间与结束时间):\n");
scanf("%s%s",(&item.bus_time)->start,(&item.bus_time)->finish);
insertHash(pHash,item);
break;
case 2:
printf("请输入你要查询的公交编号:\n");
scanf("%s",item.bus_id);
pTmp=searchHash(pHash,item);
printf("公交编号:%s\n公交车车牌号:%s\n司机姓名:%s\n",pTmp->data.bus_id,pTmp->data.bus_number,pTmp->data.bus_driver);
printf("公交车途径站信息:\n");
int j=0;
while(1)
{
if(strcmp(pTmp->data.bus_place[j],"over")==0) break;
printf(">>>>%s",pTmp->data.bus_place[j]);
j++;
}
printf("\n");
printf("公交车运营时间:\n%s-------%s\n",pTmp->data.bus_time.start,pTmp->data.bus_time.finish);
break;
case 3:
printf("请输入你要查询的公交编号:\n");
scanf("%s",item.bus_id);
printf("请输入你要修改的公交车司机信息:\n");
scanf("%s",item.bus_driver);
updataHash(pHash,item);
break;
case 4:
showHash(pHash,10);
break;
case 5:
printf("请输入你要删除的公交编号:\n");
scanf("%s",item.bus_id);
deleteHash(pHash,item);
break;
case 6:
printf("请输入你要保存的文件名:\n");
scanf("%s",file);
saveFile(pHash,file);
break;
case 7:
printf("请输入读取的文件名:\n");
scanf("%s",file);
readFile(pHash,file);
break;
case 8:
printf("%p---",pHash);
destoryLink(&pHash);
printf("%p---",pHash);
}
}
return 0;
}
注意
-
文件存储时为 二进制存储不能直观阅读,可以通过将文件写入来阅读。
-
销毁后Hash表不在存在,所以销毁Hash表后不能进行增、删、改、查。