收藏 分享(赏)

西文图书管理系统.doc

上传人:精品资料 文档编号:10619770 上传时间:2019-12-07 格式:DOC 页数:23 大小:369.50KB
下载 相关 举报
西文图书管理系统.doc_第1页
第1页 / 共23页
西文图书管理系统.doc_第2页
第2页 / 共23页
西文图书管理系统.doc_第3页
第3页 / 共23页
西文图书管理系统.doc_第4页
第4页 / 共23页
西文图书管理系统.doc_第5页
第5页 / 共23页
点击查看更多>>
资源描述

1、9西文图书管理系统图书管理基本业务活动包括:对一本书的采编入库、清除库存、借阅和归还等等。试设计一个图书管理系统,将上述业务活动借助于计算机系统完成。要求:(1 )每种书的登记内容至少包括书号、书名、著者、现存量和总库存量等五项。(2 )作为演示系统,不必使用文件,全部数据可以都在内存存放。要用 B-树(4 阶树)对书号建立索引,以获得高效率。(3 )系统应有以下功能:采编入库、清除库存、借阅、归还、显示(以凹入表的形式显示)等。1需求分析设计一个西文图书管理系统, 将图书管理基本业务活动如对一本书的采编入库、清除库存、借阅和归还等等借助于计算机系统完成,该图书管理系统应有以下功能:采编入库、

2、清除库存、借阅、归还、显示等。要求用 B-树(4 阶树)对书号建立索引,以获得高效率,输出以凹入表的形式显示。2设计2.1 设计思想(1 )数据结构设计逻辑结构设计:树形结构(B-树)存储结构设计:链式存储结构选择 B-树这种数据结构的原因:与二叉树相比,B-树是一种平衡多叉排序树。平衡是指所有叶结点都在同一层上,从而可避免出现二叉排序树那样的分支退化现象;多叉是指多于二叉,多于二叉的排序树将降低二叉树高度,从而减少查找数据元素时的比较次数。由于限制了除根结点以外的非叶子结点,至少含有 M/2 个儿子,确保了结点的至少利用率,其最底搜索性能为:其中,M 为设定的非叶子结点最多子树个数,N 为关

3、键字总数; 所以 B-树的性能总是等价于二分查找(与 M 值无关),也就没有 B 树平衡的问题;因此,B- 树是一种动态查找效率较二叉排序树更高的树形结构。(2 )算法设计算法设计的总体设计思路为:首先创建一颗 4 阶 B-树,然后在此基础上设计添加图书、查找图书、借阅图书、归还图书、显示图书状态、删除图书记录、退出七个模块,最后主函数再用一个 switch 选择语句来调用各个模块。各个模块要完成的主要功能分别为:添加图书:可以添加图书记录,按提示依次输入书号、书名、作者、现存量、总量,会提示是否继续添加。查找图书:可根据输入的书号进行查询,成功找到后会提示是否想借这本书,输入 1 为借书,输

4、入 0 为退出。借阅图书:可根据提示输入相应的书号进行借书。归还图书:可根据提示输入相应的书号归还图书。显示图书状态:可显示图书管理系统里的所有图书状态。删除图书记录:可根据提示输入相应的书号删除图书记录。主程序的流程图如下:输入 i判断 i显示图书状态删除图书记录查找图书借阅图书读取文件退出归还图书添加图书作者总量现存量书号书名开始关闭2.2 设计表示(1 )函数调用关系图(2 )函数接口规格说明int Search(BTNode *p,KeyType k)Result SearchBTree(BTNode *return 删除图书记录模块printf(请输入书号)scanf(书号)if S

5、earchBTree(书号)=trueprintf(书的具体信息:书号,书名,作者,现存量,总量)printf(输入 1 删除这本书)scanf()if(1)书号=0printf(删除成功!)else printf(操作失败!不存在这本书)return 显示图书状态模块int i;for(i=1;i#include#include #include#include #define MAXM 10 /*定义 B-树的最大的阶数*/typedef int KeyType; /*KeyType 为关键字类型*/struct BookInfo /书结构体int number;char name30;c

6、har author30;int extant;int total;typedef struct node /B-树结点定义 int keynum; /*结点当前拥有的关键字的个数*/KeyType keyMAXM; /*key1keynum存放关键字,key0不用*/struct node *parent; /*双亲结点指针*/struct node *ptrMAXM; /*孩子结点指针数组 ptr0keynum*/ BTNode;BTNode *bookp=NULL;typedef struct /*B-树的查找结果类型*/BTNode *pt; /*指向找到的结点*/int i; /*1

7、m,在结点中的关键字序号*/int tag; /*1:查找成功,O:查找失败*/ Result;int m; /*m 阶 B-树,为全局变量*/int Max; /*m 阶 B-树中每个结点的至多关键字个数,Max=m-1*/int Min; /*m 阶 B-树中非叶子结点的至少关键字个数,Min=(m-1)/2*/Result s;int Search(BTNode *p,KeyType k) /在 p-key1keynum中查找关键字序号 i,使得 p-keyikeyi+1int i;for(i=0;ikeynum elseq=p;/双亲结点 q 指向 pp=p-ptri;/p 变成它原来

8、的孩子结点r.i=i;/关键字序号 iif (found=1) /*查找成功*/r.pt=p;r.tag=1;/pt 指向找到的结点 p,tag 置为 1else /*查找不成功,返回 K 的插入位置信息*/r.pt=q;r.tag=0;/pt 指向 q,tag 置为 0return r; /*返回 k 的位置(或插入位置)*/void Insert(BTNode *for(j=q-keynum;ji;j-) /*空出一个位置*/q-keyj+1=q-keyj;q-ptrj+1=q-ptrj;q-keyi+1=x;q-ptri+1=ap;if (ap!=NULL) ap-parent=q; q

9、-keynum+;void Split(BTNode */分裂的位置ap=(BTNode *)malloc(sizeof(BTNode); /*生成新结点*ap*/ap-ptr0=q-ptrs; /*后一半移入 ap*/for (i=s+1;ikeyi-s=q-keyi;ap-ptri-s=q-ptri;if (ap-ptri-s!=NULL)ap-ptri-s-parent=ap; ap-keynum=q-keynum-s; ap-parent=q-parent; for (i=0;ikeynum-s;i+) /*修改指向双亲结点的指针*/if (ap-ptri!=NULL) ap-ptri

10、-parent = ap;q-keynum=s-1; /*q 的前一半保留,修改 keynum*/void NewRoot(BTNode *t-keynum=1;t-ptr0=p;t-ptr1=ap;t-key1=x;if (p!=NULL) p-parent=t; if (ap!=NULL) ap-parent=t;t-parent=NULL;void InsertBTree(BTNode *int finished,needNewRoot,s;KeyType x;if (q=NULL) /*t 是空树(参数 q 初值为 NULL)*/NewRoot(t,NULL,k,NULL); /生成仅

11、含关键字 k 的根结点*telse x=k;ap=NULL;finished=needNewRoot=0; while (needNewRoot=0 /*将 x 和 ap 分别插入到 q-keyi+1和 q-ptri+1*/if (q-keynumkeys+1m,q-ptrsm和 q-recptrs+1m移入新结点*ap*/s=(m+1)/2;Split(q,ap); x=q-keys;if (q-parent) /*在双亲结点*q 中查找 x 的插入位置*/q=q-parent;i=Search(q, x); else needNewRoot=1;if (needNewRoot=1) /*根

12、结点已分裂为结点*q 和*ap*/NewRoot(t,q,x,ap); /*生成新根结点*t,q 和 ap 为子树指针*/void Remove(BTNode *p,int i)/*从*p 结点删除 keyi和它的孩子指针 ptri*/int j;for (j=i+1;jkeynum;j+) /*前移删除 keyi和 ptri*/p-keyj-1=p-keyj;p-ptrj-1=p-ptrj;p-keynum-;void Successor(BTNode *p,int i)/*查找被删关键字 p-keyi(在非叶子结点中)的替代叶子结点*/BTNode *q;for (q=p-ptri;q-p

13、tr0!=NULL;q=q-ptr0);p-keyi=q-key1; /*复制关键字值*/void MoveRight(BTNode *p,int i)/*把一个关键字移动到右兄弟中*/int c;BTNode *t=p-ptri;for (c=t-keynum;c0;c-) /*将右兄弟中所有关键字左移一位*/t-keyc+1=t-keyc;t-ptrc+1=t-ptrc;t-ptr1=t-ptr0; /*从双亲结点移动关键字到右兄弟中*/t-keynum+;t-key1=p-keyi;t=p-ptri-1; /*将左兄弟中最后一个关键字移动到双亲结点中*/p-keyi=t-keyt-key

14、num;p-ptri-ptr0=t-ptrt-keynum;t-keynum-;void MoveLeft(BTNode *p,int i)/*把一个关键字移动到左兄弟中*/int c;BTNode *t;t=p-ptri-1; /*把双亲结点中的关键字移动到左兄弟中*/t-keynum+;t-keyt-keynum=p-keyi;t-ptrt-keynum=p-ptri-ptr0;t=p-ptri; /*把右兄弟中的关键字移动到双亲兄弟中*/p-keyi=t-key1;p-ptr0=t-ptr1;t-keynum-;for (c=1;ckeynum;c+) /*将右兄弟中所有关键字移动一位*

15、/t-keyc=t-keyc+1;t-ptrc=t-ptrc+1;void Combine(BTNode *p,int i)/*将三个结点合并到一个结点中*/int c;BTNode *q=p-ptri; /*指向右结点,它将被置空和删除*/BTNode *l=p-ptri-1;l-keynum+; /*l 指向左结点*/l-keyl-keynum=p-keyi;l-ptrl-keynum=q-ptr0;for (c=1;ckeynum;c+) /*插入右结点中的所有关键字*/l-keynum+;l-keyl-keynum=q-keyc;l-ptrl-keynum=q-ptrc;for (c=

16、i;ckeynum;c+) /*删除父结点所有的关键字*/p-keyc=p-keyc+1;p-ptrc=p-ptrc+1;p-keynum-;free(q); /*释放空右结点的空间*/void Restore(BTNode *p,int i)/*关键字删除后,调整 B-树,找到一个关键字将其插入到 p-ptri中*/if (i=0) /*为最左边关键字的情况*/if (p-ptr1-keynumMin)MoveLeft(p,1);elseCombine(p,1);else if (i=p-keynum) /*为最右边关键字的情况*/if (p-ptri-1-keynumMin)MoveRig

17、ht(p,i);elseCombine(p,i);else if (p-ptri-1-keynumMin) /*为其他情况*/MoveRight(p,i);else if (p-ptri+1-keynumMin)MoveLeft(p,i+1);elseCombine(p,i);int SearchNode(KeyType k,BTNode *p,int return 0;else /*在*p 结点中查找*/i=p-keynum;while (kkeyi return(k=p-keyi);int RecDelete(KeyType k,BTNode *p)/*查找并删除关键字 k*/int i;

18、int found;if (p=NULL)return 0;elseif (found=SearchNode(k,p,i)=1) /*查找关键字 k*/if (p-ptri-1!=NULL) /*若为非叶子结点*/Successor(p,i); /*由其后继代替它*/RecDelete(p-keyi,p-ptri); /*p-keyi在叶子结点中*/elseRemove(p,i); /*从*p 结点中位置 i 处删除关键字*/elsefound=RecDelete(k,p-ptri); /*沿孩子结点递归查找并删除关键字 k*/if (p-ptri!=NULL)if (p-ptri-keynu

19、mkeynum=0)p=root;root=root-ptr0;free(p);struct BookInfo book1000;void addbook()/添加书int n=1,num;while(n)printf(“书号:“);scanf(“%d“,s=SearchBTree(bookp,num);if(s.tag=1)printf(“此书已存在!“);elsebooknum.number=num;printf(“n 书名:“);scanf(“%s“,printf(“n 作者:“);scanf(“%s“,printf(“n 现存量:“);scanf(“%d“,printf(“n 总量:“

20、);scanf(“%d“,InsertBTree(bookp,booknum.number,s.pt,s.i);printf(“n 输入 1 继续添加, 0 返回主界面“);scanf(“%d“,void lendbook(int booknumber)/借书int num;if(booknumber=-1)printf(“请输入书号:“);scanf(“%d“,if(booknum.extant)printf(“操作成功!“);booknum.extant-;elseprintf(“操作失败!书已经被借出或不存在这本书.“);elseprintf(“操作成功!n“);bookbooknumb

21、er.extant-;return;void findbook()/查找书int num,select;printf(“请输入书号:“);scanf(“%d“,s=SearchBTree(bookp,num);if(s.tag) printf(“成功找到!.n“);printf(“书号:%d,nt 书名:%s,作者:%s,现存量:%d,总量:%dn“,booknum.number,booknum.name,booknum.author,booknum.extant,booknum.total);elseprintf(“此书不存在.“);if(booknum.extant)printf(“你想借

22、这本书吗?输入 1 借, 0 退出.n“);scanf(“%d“,if(select)lendbook(num);else return;elsereturn;void returnbook()/还书int num;printf(“请输入书号:“);scanf(“%d“,if(booknum.number!=-1printf(“操作成功!n“);else printf(“操作失败!n“);return;void delbook()/删除int num;int confirm;printf(“请输入书号:“);scanf(“%d“,printf(“书的具体信息:n 书号:%d,nt 书名:%s,

23、作者%s,现存量%d,总量%dn“,booknum.number,booknum.name,booknum.author,booknum.extant,booknum.total);printf(“输入 1 删除这本书:“);scanf(“%d“,if(confirm=1)DeleteBTree(booknum.number,bookp);booknum.number=0;printf(“删除成功!“);return;void bookcount()/显示书的状况int i;for(i=1;i1000;i+)if(booki.number!=0)printf(“书号:%3d, nt 书名:%7

24、s, 作者:%7s, 现存量:%5d, 总量:%5dn“,booki.number,booki.name,booki.author,booki.extant,booki.total);void menu()/主界面printf(“ntt 操作选单n“); printf(“t1 新添书籍nt2 查找图书n“);printf(“t3 借阅图书n“); printf(“t4 归还图书nt5 图书状态n“);printf(“t6 删除图书记录n“);printf(“t7 退出n“); switch(getch() case 1 : addbook() ;break;case 2 : findbook() ;break; case 3 : lendbook(-1) ;break;case 4 : returnbook();break;case 5 : bookcount() ;break;case 6 : delbook() ;break;case 7 : exit(0) ; int main()/主函数int j,n=20;m=4; Max=m-1;Min=(m-1)/2;for (j=0;j1000;j+) /*创建一棵 4 阶 B-树 t*/ s=SearchBTree(bookp,bookj.number);if (s.tag=0 while(1)menu();return 0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报