广工数据结构课程设计报告图书管理系统Word格式文档下载.docx
《广工数据结构课程设计报告图书管理系统Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《广工数据结构课程设计报告图书管理系统Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
各个数据元素均含有类型一样,可惟一标识数据元素的关键字。
数据关系:
数据元素同属于一个集合并且:
一棵m阶的B树,或为空,或为满足以下特性的m叉树:
树中每个结点至多有m棵子树;
假设根结点不是叶子结点,那么至少有两棵子树;
除根之外的所有非终端结点至少有m/2〔取上限〕棵子树;
所有的非终端结点包含以下信息数据:
(n,A0,K1,A1,K2,A2,K3,……,Kn,An)
其中:
Ki〔i=1,2,……n〕为关键字,且Ki<
Ki+1〔i=1,2,……n-1〕;
Ai〔i=0,……n〕为指向子树根结点的指针,且指针Ai-1所指子树中所有结点的关键字均小于Ki〔i=1,2,……n〕,An所指子树中所有结点的关键字均大于Kn,n〔m/2(取上限)-1<
=n<
=m-1〕为关键字的个数
根本操作:
CreateBTree(BTree*T)
操作结果:
构建B-树
BTreeSearch(sBTree*T,intk,sBTree*&
x,int&
index)
初始条件:
树T存在,k为和关键字类型一样的给定值。
操作结果:
假设B树T中存在关键字等k的数据元素,那么返回该元素的值或在表中的位置,否那么返回“空〞。
BTreeInsert(k)
初始条件:
B树T存在,k为待插入的数据元素。
假设T中不存在关键字等于k的数据元素,那么插入k到T中。
BTreeDeleteKeywords(sBTree*T,k);
B树T存在,k为和关键字一样的给定值。
假设T中存在其关键字等于k的数据元素,那么删除之。
BTreeTraverse(BTreeT,Visit)
B树T存在,Visit是对T结点的函数
遍历B树T,对每个结点调用Visit函数
PrintBTree(sBTree*T);
书库T存在。
以凹入表形式显示B树T。
}ADTBTree
〔2〕.图书管理类型定义:
ADTBook{
D={ai|ai∈BookType,i=1,2,3,……n,n>
=0,其中
每个数据元素ai含有类型一样,可惟一标识数据元素的关键字}
数据元素同属一个集合
InsertBook(sBTree*T,sKeywordskeywords)
B树T已存在。
如果所要插入的书中已存在T树中,那么只将该书的库存量增加,否那么插入到T树中。
Rent(k)
书库不为空。
如果书库中有书号为k的书,那么借书成功,否那么返回查找失败。
Get(k)
如果书库中有书号为k的书,那么还书成功,否那么返回查无此书。
}ADTBook
〔3〕主程序
intmain()
{初始化
系统界面;
do
{switch()
显示菜单信息;
承受命令;
处理命令;
输出结果;
}while
}
3.详细设计
〔1〕抽象数据类型B-树存储定义:
structsBTree{
intn;
//关键字的计量
sKeywordskeywords[MAX_KEYWORDS];
//关键字的最大容量
boolleaf;
//判断是否为叶子
sBTree*children[MAX_KIDSNUM];
//孩子
};
sBTree*root=NULL;
//根结点
intdeep=0;
//深度
voidCreateBTree();
//构建B树
boolBTreeSearch(sBTree*T,intcount,sBTree*&
index);
//查找关键字
voidBTreeInsert(sKeywordskeywords);
//插入
voidBTreeInsertNonfull(sBTree*x,sKeywordskeywords);
//非满B树的插入
voidBTreeDeleteKeywords(sBTree*x,intcount);
//删除结点
voidBTreeSplitChild(sBTree*parent,inti);
//分裂孩子结点
sBTree*BTreeSplit(sBTree*x,sKeywords&
keywords);
//分裂结点
voidBTreebine(sBTree*x,sKeywordskeywords,sBTree*newNode)//结点合并
(2)B-树操作定义
voidCreateBTree()
{//构建B-树
sBTree*newNode=(sBTree*)malloc(sizeof(sBTree));
//分配存储空间
newNode->
leaf=true;
n=0;
root=newNode;
for(inti=0;
i<
MAX_KIDSNUM;
i++)
root->
children[i]=NULL;
boolBTreeSearch(sBTree*T,intcount,sBTree*&
{//查找操作
inti=0;
while(i<
(T->
n)&
&
count>
keywords[i].count))
i++;
if(i<
count==(T->
keywords[i].count)){
x=T;
index=i;
returntrue;
}
if(T->
leaf)
returnfalse;
else
returnBTreeSearch(T->
children[i],count,x,index);
voidBTreeInsert(sKeywordskeywords)
{//插入操作
sBTree*r=root;
if(r->
n==MAX_KEYWORDS){//如果结点B树已满,那么分配新的结点
leaf=false;
children[0]=r;
BTreeSplitChild(newNode,0);
BTreeInsertNonfull(newNode,keywords);
BTreeInsertNonfull(r,keywords);
voidBTreeInsertNonfull(sBTree*x,sKeywordskeywords)
{
inti=(x->
n);
while(i>
0&
keywords<
x->
keywords[i-1])
i--;
if(x->
AddKeywordsToLine(x,i,keywords,NULL,true);
else{
if(x->
children[i]->
n==MAX_KEYWORDS){
BTreeSplitChild(x,i);
if(keywords>
keywords[i])
BTreeInsertNonfull(x->
children[i],keywords);
voidBTreeDeleteKeywords(sBTree*x,intcount)
{//删除结点
sKeywordskeywords;
sBTree*newNode;
intindex=-1;
leaf){
BTreeDeleteLeafData(x,count);
elseif(DataInNode(x,count,index)){
if((x->
children[index]->
n)>
MIN_KEYWORDS){
keywords=MaxKeywords(x->
children[index]);
x->
keywords[index]=keywords;
BTreeDeleteKeywords(x->
children[index],keywords.count);
elseif((x->
children[index+1]->
keywords=MinKeywords(x->
children[index+1]);
children[index+1],keywords.count);
newNode=RemoveKeywordsFromLine(x,index,keywords,false);
BTreebine(x->
children[index],keywords,newNode);
children[index],count);
for(index=0;
index<
n;
index++){
if(count<
keywords[index].count)
break;
n==MIN_KEYWORDS){
if(index>
(x->
children[index-1]->
n)>
MIN_KEYWORDS){
newNode=RemoveKeywordsFromLine(x->
children[index-1],x->
n-1,keywords,false);
AddKeywordsToLine(x->
children[index],0,x->
keywords[index-1],newNode,false);
keywords[index-1]=keywords;
elseif(index<
(x->
n>
MIN_KEYWORDS))
children[index+1],0,keywords,true);
children[index],x->
n,x->
keywords[index],newNode,true);
if(index==0){
newNode=RemoveKeywordsFromLine(x,index-1,keywords,false);
children[index-1],keywords,newNode);
children[index-1],count);
newNode=root;
while(root->
n==0){
newNode=root->
children[0];
free(root);
(3)图书管理存储定义
voidprintBTree(sBTree*T);
//B树的形式显示当前所有的图书号
voidprintTab();
voidInsertBook(sBTree*T,sKeywordskeywords);
//插入新书
sKeywordsMakeNewBook();
//输入新书的信息
voidrent(intcount);
//借书
voidget(intcount);
//还书
〔4〕图书管理函数定义
sKeywordsMakeNewBook()//输入新书的信息
printf("
请输入新书编号:
\n"
);
scanf("
%d"
&
(keywords.count));
请输入新书名称:
%s"
keywords.name);
请输入新书\n"
keywords.author);
请输入新书数量:
(keywords.allReserves));
keywords.reserves=keywords.allReserves;
//现有数量等于库存量
returnkeywords;
voidInsertBook(sBTree*T,sKeywordskeywords)//插入新书
intindex;
sBTree*x;
boolexist=BTreeSearch(T,keywords.count,x,index);
if(exist){
keywords[index].allReserves+=keywords.allReserves;
//库存增加
keywords[index].reserves+=keywords.reserves;
//现有量增加
BTreeInsert(keywords);
voidrent(intcount)//借书,书库中有书号为count的书,借阅成功,否那么“查找
//失败
if(BTreeSearch(root,count,x,index)&
keywords[index].reserves>
0))
keywords[index].reserves--;
查找失败!
voidget(intcount)//还书,如果书库中有书号为count的书,那么可归还
{//假设无,那么输出“查无此书〞。
if(BTreeSearch(root,count,x,index))
keywords[index].reserves++;
查无此书!
voidprintBTree(sBTree*T)//B树的形式显示当前所有的图书号
if(T==NULL)
return;
T->
i++){
printTab();
%d\n"
T->
keywords[i].count);
else{
deep++;
printBTree(T->
children[i]);
deep--;
children[T->
n]);
voidprintTab()//按制表位输出书号
deep;
\t"
(5)主函数
voidmain()
{
sKeywordskeywords;
intcount;
//书号
charchoice;
CreateBTree();
printf("
\n\n"
图书管理系统主菜单\n"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
☆1----采编入库☆\n\n"
☆2----去除库存☆\n\n"
☆3----借阅☆\n\n"
☆4----归还☆\n\n"
☆5----显示☆\n\n"
☆6----退出☆\n\n"
请选择相应编码:
"
do{
%c"
choice);
switch(choice)
{
case'
1'
:
//采编入库
keywords=MakeNewBook();
InsertBook(root,keywords);
2'
//去除库存
要删除的书编号为:
count);
BTreeDeleteKeywords(root,count);
3'
要借出的书编号为:
rent(count);
4'
归还的树编号为:
"
get(count);
5'
//退出
printBTree(root);
default:
}while(choice!
='
6'
函数调用过程如以下图所示:
4.调试分析
⑴调试过程中遇到的问题以及对设计与实现的回忆讨论和分析:
对于本次设计个人感觉难度很大,因为图书管理系统涉及到的功能比拟多,采编入库、去除库存、借阅和和归还,其中最难的局部是B树定义和操作以及B树相关操作的调用,书上对于B树这一块的容比拟少,网上B树的根本操作和算法很少,因此在B树的插入和删除算法上花了很多时间,后来通过网上查找资料跟同学讨论得出。
此外,因为涉及的算法和代码比拟多,很容易出各种各样的错,在编译面也花了不少时间。
⑵算法的时空分析:
这个图书管理系统的存储时建立在存上的,故程序退出数据得不到保存,每个功能感觉比拟独立,相互间联系不算多,想要提高根本操作和算法的效率只能通过在算法的设计以及存储构造上下功夫。
⑶经历和体会:
?
数据构造?
这门课程考验的不仅仅是人的思维,更多的是考验人的耐心和洞察力,想要学好这一门课程,掌握根本要领,以及编写出执行能力各面都强的程序需要花更多的时间去钻研;
在编写过程中,会出现各种各样细节上的问题,大到一条算法,小到一个“=〞与“==〞或者是“;
〞与“;
〞都可能成为你的障碍,细心和结实的根底知识很重要。
5.用户使用说明
1.本程序运行环境为VC6.0,执行文件为:
图书管理系统.exe;
2.程序界面与菜单信息
选择1:
采编入库,新书购入,将书号、书名、著者、册数、出版时间添参加图书账目中去,如果这种书在帐中已有,那么只将总库存量增加,每新增一个书号那么以凹入表的形式显示B树现状。
选择2:
去除库存,实现某本书的全部信息删除操作,没去除一个书号那么已以凹入表的形式显示B树现状。
选择3:
图书借阅,如果书的库存量大于零时那么执行出借,登记借阅者的图书证号和XX,系统自动抓取当前借阅时间和计算归还时间。
选择4:
图书归还,注销借阅者信息,并改变该书的现存量。
选择5:
显示输出。
选择6:
平安退出。
6.测试结果
测试数据:
入库书号:
分别删除书号:
45、90、50、22、42
(1)新书入库界面如下:
〔2〕所有的书号录入完毕后以B树形式显示:
〔3〕分别删除书号45、90、50、22、42
(4)删除后以B树形式显示剩下所有的书号
(5)当只向系统中录入书号为35的书时,以下为借书号为12和书号为35、还书号为12和还书号为35的运行情况〔成功和失败的测试结果〕
7.附录