数据结构课程设计模板.docx
《数据结构课程设计模板.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计模板.docx(26页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计模板.docx](https://file1.bdocx.com/fileroot1/2022-12/16/529c5d93-4aad-41af-a5f7-e1b4dffa337a/529c5d93-4aad-41af-a5f7-e1b4dffa337a1.gif)
数据结构课程设计模板
数据结构课程设计
图书馆管理基本业务模拟
学生姓名:
学号:
指导教师:
完成日期:
目录
1设计任务书3
1.1题目与要求3
1.2设计知识点3
1.3输入输出分析3
1.4测试数据分析3
2概要设计4
2.1结构体类型及函数声明4
2.2主程序流程5
2.3模块流程说明5
3详细设计8
3.1数据类型实现8
3.2程序伪码9
4调试分析17
4.1问题分析与回顾17
4.2算法时空分析18
4.3算法改进18
4.4经验和体会18
5测试结果19
参考文献(要求不少于10篇)22
1设计任务书
1.1题目与要求
题目:
编写程序实现图书馆管理业务的模拟。
要求:
书的登记内容包括书号、书名、著作者、出版社、现存量和库存量。
并且按书号建立索引表以提高索引效率。
程序要能够实现一下功能:
a.采编入库:
新购一本书,确定书号后,则登记到图书账目中,如果表中以有,则只将库存增加。
b.借阅:
如果书的库存量大于0,则借出一本书,登记借阅者的借书证号和归还日期,改变现存量。
C.归还:
注销对借阅者的登记,改变书的现存量。
1.2知识点
系统时间函数、系统调用库函数、索引表建立、文件、结构体、指针、链表、数组、循环语句、选择语句、输入输出控制、宏定义、自定义类型等。
1.3输入输出分析
(1)普通输入
对于书籍内容登记及读者信息宜采用结构体进行存储,其中的具体单项信息则采用字符数组或整形变量直接存续,考虑到书籍及读者信息的具体内容,字符数组长度为20较为合适。
(2)对话式输入
为便于转换及比较,对话式输入采用字符数组进行存储.为保障程序的健壮性,同时限制对话式输入的格式,对于非法的会话式输入则提示用户操作失败的原因;此外为保障用户在任意一步回话操作中都能任意退出,在程序中设计一“特殊按键”,当输入时,则程序返回上一层。
(3)程序输出
对于书籍信息及读者借阅信息的显示,考虑到美观及直观的因素,则采用表格的形式进行显示;此外对于借书及还书过程中,为保障操作无误,则在用户选择后,对用户的操作进行输出,并请用户进行确认;在对话式输入中,对于非法输入,程序显示的提示信息采用下划线进行强调,以引起用户的注意。
1.4测试数据分析
书籍登记入库操作中如果书籍登录号超过六位则应提示”格式错误”;如果书号或书名已存在,则应提示”书籍已存在”。
如果操作正确,则提示“书籍已登记入库”。
在书刊检索中,如果书刊存在则应显示书籍信息,如果不存在则应提示“书籍不存在”。
在读者信息登记操作中,如果读者以存在,则应提示”读者已存在”.否则,提示“成功添加读者”。
在读者登录过程中,如果读者信息错误,则提示“用户名或密码错误”,否则登录操作。
借书还书中的输出类似于检索中的提示。
2概要设计
2.1结构体类型及函数声明
(1)结构体
图书信息结构体类型 BOOK
读者信息结构体类型 READER
日期结构体类型 DATE
索引项结构体类型 IDXTYPE
索引表结构体类型 ISXLIST
(2)函数声明
intInfo_show(BOOK*p,intn)//书籍信息显示函数
intBSave(BOOK*L)//书籍信息导出函数
intBLoad(BOOK*L)//书籍信息导入函数
intBOOK_SORT(BOOK*B,BOOK*P)//按照书号排序函数
intStore_in_lib(BOOK*B)//书籍登记入库函数
intRSave(READER*R)//读者信息导出函数
intRLoad(READER*R)//读者信息导入函数
READER*Search_r(READER*R,READERT)//查找读者函数
BOOK*Search_writer(BOOK*B)//按作者查找函数
BOOK*Search_name(BOOK*B,intn)//按书名查找函数
IDX_LIST*IDX_FORM(BOOK*B)//索引表生成函数
BOOK*Search_num(BOOK*B,intn)//按书号查找函数
intSearch_menu(BOOK*B)//书籍检索菜单
intIf_stop(DATE*time)//判断时间循环是否停止函数
DATE*RTIME()//还书日期函数
intLend(READER*tp,BOOK*B)//借书函数
intReturn(READER*tp,BOOK*B)//还书模块
intLog_menu(READER*R,READER*tp,BOOK*B)//读者登录函数
intLog_in(READER*R,BOOK*B)//读者登录模块
READER*REA_SORT(READER*R,READER*p)//读者排序函数
intTEACHER_LOG()//管理员登录函数
intREA_INSERT(READER*R)//读者信息插入函数
intTeacher(READER*R)//管理员登录主调函数
intLibrary_menu(void)//管理函数主菜单
intWELCOME()//系统欢迎菜单
intShow_all(BOOK*B)//藏书一览函数
intCHOICE(BOOK*B,READER*R)//函数主调菜单
2.2主程序流程
(1)主程序调用模块图
主程序利用switch()语句实现各个模块的调用,主函数调用如图1所示。
图1主程序调用模块图
2.3模块流程说明
主函数对各主要模块进行调用,各个主要模块又分别调用其他子模块。
下面用简要流程图对各主要模块进行说明。
(1)登记入库主模块
如图2所示,为登记入库模块。
先通过键盘读取书记信息,再调用Info_show()函数显示该书籍信息,用户确认信息无误,调用Store_in_lib函数登记入库,如用户不希望此次操作,则放弃退出,返回上级目录。
图2登记入库模块
(2)用户登录主模块
如图3所示为用户登录流程图。
录入借书号及密码,判断合法则登陆,否则结束。
图3用户登录模块
(3)书刊检索主模块
如图4为书刊检索流程图。
首先录入读者需要按照哪种方式进行检索,系统判断检索方式,调用相应的函数查找,并返回检索的结果。
图4书刊检索主模块
(4)管理员登录模块
如图5所示为管理员登陆流程图。
首选录入管理员账号及密码,系统调用TEACHER_LOG()函数,判断账号的合法性,如合法,管理员履行管理功能,不合法提示错误,退出。
图5管理员登录模块
3详细设计
3.1数据类型实现
图书信息结构体
typedefstructBOOK_INFO
{
charB_num[20];
charB_name[20];
charB_writer[20];
charB_publer[20];
charB_ptime[20];
intNow_store;
intTotal_store;
structBOOK_INFO*next;
}BOOK;
读者信息结构体
typedefstructREADER
{
charRea_name[20];
charRea_code[20];
charRea_num[20];
charBOOKlenb[5];
DATERtime[5];
structREADER*next;
}READER;
还书日期结构体
typedefstruct{
intyear;
intmonth;
intday;
}DATE;
索引表结构体
Typedefstruct{
IDXTYPEidxterm[100];
intlen;
}IDX_LIST;
索引项结构体
typedefstructIDX_TERM{
charnum[8];
intlen;
BOOK*P;
}IDXTYPE;
3.2程序代码
intY_N()
//根据读取的字符给flag赋不同值,并返回flag的值
{
scanf(ch);
if(ch[0]=='Y'||ch[0]=='y')flag=1;if(ch[0]!
='y'&&ch[0]!
='Y'&&ch[0]!
='n'&&ch[0]!
='N')
flag=0;
if(ch[0]=='N'||ch[0]=='n')flag=-1;
}
intStore_in_lib(BOOK*B)
//读取书籍信息并经用户确认后插入书籍链表B中
{
q=B;
do
{
if(!
(tp=(BOOK*)malloc(sizeof(BOOK))))
returnerror;
*tp=NULB;//所用信息都为空的书籍宏定义
do{
scanf(tp->B_num);
}while(strlen(tp->B_num)!
=6);for(exit=B->next;exit&&strcmp(exit->B_num,tp->B_num);exit=exit->next);//判断书号是否已经存在
if(!
exit)
{
scanf(tp->B_name);for(exit=B->next;exit&&strcmp(exit->B_name,tp->B_name);exit=exit->next);//判断书是否已经存在
if(exit)
{
exit->Now_store++;
exit->Total_store++;
}
}
else
{
scanf(tp);
tp->next=NULL;
Info_show(tp,0);
do//确认是否登记入库
{
Flag=Y_N();
}while(!
flag);
if(flag==1)BOOK_SORT(B,tp);//插入链表
if(flag==-1)free(tp);//释放空间
}
}
do//确认是否继续
{
flag=Y_N();
}while(!
flag);
}while(flag==1);
return0;}
BOOK*Search_writer(BOOK*B)
//从键盘读取著作者的名字,在书籍链表中查找,如果存在则返回满足//条件的指针,否则返回空指针
{
scanf(writer);
p=B->next;
while(p)
{
if(!
(strcmp(p->B_writer,writer)))
break;
p=p->next;
}
if(p)
Info_show(p,0);
returnp;
}
BOOK*Search_name(BOOK*B)
//从键盘读取书籍名称,如果书籍存在,则返回书记信息指针,否则返//回空指针
{
scanf(name);
p=B;
while(p)
{
if(!
(strcmp(p->B_name,name)))
break;
p=p->next;
}
if(p)
{p->next=NULL;
Info_show(p,0);
}
returnp;
}
IDX_LIST*IDX_FORM(BOOK*B)
//根据书籍信息链表B建立书号索引表,并返回索引表的头指针
{
if(!
(List=(IDX_LIST*)malloc(sizeof(IDX_LIST))))
returnNULL;
List->len=0;
List->idxterm[0].len=0;//初始化
tp=B->next;
if(tp)
{
do{
if(i==0&&List->idxterm[0].len==0)
{
strcpy(List->idxterm[i].num,tp->B_num);
memcpy(flag,tp->B_num,2);
List->idxterm[i].len=1;
List->len=1;
tp=tp->next;
continue;
}//将第一本书的书号做为索引表的第一项并以第一项//的前两个字符作为关键字
memcpy(temp,tp->B_num,2);//将tp->B_num的前两个字符赋值//给temp
if(strcmp(flag,temp))
{
i++;
strcpy(List->idxterm[i].num,tp->B_num);
memcpy(flag,tp->B_num,2);
List->idxterm[i].len=1;
}//增加新的索引项
else
List->idxterm[i].len++;//记录关键字相同的数量
List->len=i+1;
tp=tp->next;
}while(tp);
}
returnList;
}
BOOK*Search_num(BOOK*B,intn)
//根据书号查找书籍,如果找到则返回书籍指针,并使书籍的现存量n;
//否则返回空指针
{
BOOK*tp;
inti,j,Len=0,flag=0;
charnum[8];
IDX_LIST*IList;
if(!
(IList=(IDX_LIST*)malloc(sizeof(IDX_LIST))))
returnNULL;
IList->len=0;
tp=B->next;
if(tp)
IList=IDX_FORM(B);
else
{
tp=NULL;
returntp;
}
scanf(num);
for(i=0;ilen&&!
flag;i++)
{
if(strcmp(num,IList->idxterm[0].num)<0)//如果小于第一项索//引项则书籍不存在
{
tp=NULL;
returntp;
}
elseif(strcmp(num,IList->idxterm[i+1].num)<0||i==IList->len-1)//比较与索引表下一项的大小
{
for(j=0;j
Len+=IList->idxterm[j].len;//计算指针移动的次数
for(j=1;j<=Len;j++)
tp=tp->next;//移动指针
for(j=1;j<=IList->idxterm[i].len;j++)
{
if(!
strcmp(tp->B_num,num))
{
if(!
(n<0&&(tp->Now_store==0)))
tp->Now_store+=n;//根据主调函数改变现存量
flag=1;
break;
}
tp=tp->next;
}
if(j-1==IList->idxterm[i].len&&!
flag)//没找到
{
tp=NULL;
returntp;
}
}
}
returntp;}
intSearch_menu(BOOK*B)
//根据用户的选择对书籍信息链表B进行不同方式的查找
{
do
{
scanf(ch);
op=atoi(ch);
}while(op<1||op>3);
switch(op)
{
case1:
Search_num(B,0);break;
case2:
Search_name(B);break;
case3:
Search_writer(B);break;
}
return0;
}
intIf_stop(DATE*time)
//判断时间time是否符合实际
{
if(time->month==4||time->month==6||time->month==9||time->month==11)
{
if(time->day<=30)
return0;
}
else
{
if((!
(time->year%4)&&(time->year%100))||
!
(time->year%400))
num=29;
else
num=28;//判断2月的天数
if(time->month==2&&time->day<=num)
return0;
elseif(time->day<=31)
return0;
}
return1;
}
DATE*RTIME()
//计算机还书日期,放回日期结构体类型的指针
{
time_tnowtime;
structtm*timeinfo;
DATE*rtime;
rtime=(DATE*)malloc(sizeof(DATE));
time(&nowtime);
timeinfo=localtime(&nowtime);
y=timeinfo->tm_year+1900;
m=timeinfo->tm_mon+1;
d=timeinfo->tm_mday;
rtime->year=y;
rtime->month=m;
rtime->day=d;
rtime->day+=60;
do
{
switch(rtime->month)
{
case4:
case6:
case9:
case11:
if(rtime->day>30)
{
rtime->month++;
rtime->day-=30;
}
break;
case2:
if((!
(rtime->year%4)&&(rtime->year%100))
||!
(rtime->year%400))
num=29;
elsenum=28;
if(rtime->day>num)
{
rtime->month++;
rtime->day-=num;
}
break;
default:
if(rtime->day>31)
{
rtime->month++;
rtime->day-=31;
}
}
if(rtime->month>12)
{
rtime->year++;
rtime->month-=12;
}
}while(If_stop(rtime));
returnrtime;
}
intLend(READER*tp,BOOK*B)
//在图书链表B中查找用户的书籍,找到后将书籍登记到读者tp名下
//并将书籍存量减一
{
BOOK*btp=NULL;
inti=0;
while(strcmp(tp->lenb[i].B_num,"NUL")&&i<5)
i++;
if(i==5)return0;//判断是否达到借书上限
btp=Search_num(B,-1);
if(btp)
{
if(btp->Now_store!
=0)
{
tp->lenb[i]=*btp;
tp->Rtime[i]=*RTIME();
}
}
return0;
}
intReturn(READER*tp,BOOK*B)
//在图书链表B中查找用户的书籍,找到后将书籍从读者tp名下删除
//并将书籍存量减一
{
inti=0;
BOOK*p;
p=Search_num(B,1);
while(strcmp(p->B_num,tp->lenb[i].B_num))
i++;
if(i<4)
{
for(;i<4;i++)
{
tp->lenb[i]=tp->lenb[i+1];
tp->Rtime[i]=tp->Rtime[i+1];
}
}
tp->lenb[4]=NULB;
return0;
}
READER*REA_SORT(READER*R,READER*p)
{
READER*tp;
tp=R;
while(tp->next)
{
if(strcmp(p->Rea_num,tp->next->Rea_num)<0)
break;
tp=tp->next;
}
returntp;
}
intTEACHER_LOG()
//教师登录验证,通过则返回0,否则返回1
{
scanf(name);
scanf(code);
if(!
strcmp(name,"李云高")&&!
strcmp(code,"121513"))
return0;
else
return1;
}
intREA_INSERT(READER*R)
//从键盘录入读者信息,并以指针存放,经用户确认后插入读者信息链//表R中
{
do
{
p=R;
while(p->next)
{
p=p->next;
}
if(!
(tp=(READER*)malloc(sizeof(READER))))
returnerror;
scanf(tp);
tp->next=NULL;
p=REA_SORT(R,tp);
tp->next=p->next;
p->next=tp;
do
{
flag=Y_N();
}while(!
flag);
}while(flag==1);
return0