数据结构课程设计图书管理系统.docx
- 文档编号:25984616
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:39
- 大小:148.37KB
数据结构课程设计图书管理系统.docx
《数据结构课程设计图书管理系统.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计图书管理系统.docx(39页珍藏版)》请在冰豆网上搜索。
数据结构课程设计图书管理系统
用C++语言实现图书管理系统
摘要图书管理系统主要是对图书的录入、读者借阅、读者归还等功能进行实现.本课程设计的系统开发平台为WindowsXP,程序设计语言为C++,程序运行平台为Windws98/2000/XP/Seven。
在程序设计中采用了B-树方法提高书籍的查找速度。
关键词程序设计;图书管理系统;C++;数据结构;B-树
1索引
1.1课程设计目的
设计一个小型的图书管理系统,可以实现新增图书,读者借阅,读者归还等功能。
1。
2。
系统性能要求
能较快的查到所要查找的图书;能准确统计当前每种书的库存,以确定此书是否可以外借;并且对外借的图书进行管理,记录借出时间、应还时间等。
1.3。
功能的实现
1)新书入库:
确定书号后,登记到图书帐目表中,如果表中已有,则只将库存量增加;
2)借阅:
如果一种书的现存量大于0,则借出一本,登记借阅者的书证号和归还期限,改变现存量;
3)归还:
注销对借阅者的登记,改变该书的现存量.
2系统详细设计及实现
1.所用的知识体系
在整个程序的设计过程当中,用到了C++的一些基础知识,面向对象的思想和结构化的程序设计思想.数据结构的B—树建立索引,用索引提高查找的效率等。
2。
系统功能组成框图
3 .系统功能模块划分
摸块保称
功能说明
1
系统管理
显示库存,借阅,归还
2
图书管理
图书的添加,查询等操作
3
借还书管理
对每次借书信息的添加,删除等操作
4。
流程图
4。
1录入图书信息
4.2借阅图书
4。
3归还图书
5功能实现
5.1运行程序的主界面
图5—1操作界面
5。
2新书入库功能的操作界面
图5—2新书入库
5.3查询数据的界面
图5-3查询书籍
5。
4查询所有书籍的界面
图5—4显示库存
5.5图书借阅的界面
图5-5借阅书籍
5。
6还书的界面
图5—6还书
3参考文献
[1] 谭浩强 C语言设计(第三版)清华大学出版社
[2]严蔚敏吴伟民数据结构(C语言版)清华大学出版社
[3]谭浩强 C++程序设计清华大学出版社
[4]参考网址
[5]参考网址
附录
#include〈stdio。
h〉
#include h> #include h> #include〈conio.h〉 #include〈time。 h> //定义局变量 #defineN10000 //表示状态的字段 #defineTRUE1 #defineFALSE0 #defineOK1 #defineERROR0 #defineINFEASIBLE-1 #defineOVERFLOW-2 typedefintStatus; typedefchar*string; #definem3//B—树的阶,设为 //借阅者的结构体 typedefstructUser{ unsignedintnumber;//借书证号码 intyear; intmonth; intday;//借书时间 intdyear;//截至日期的年 intdmonth;//截至日期的月 intdday;//截至日期的日 structUser*next;//下一个借阅者 }User;//定义用户的的信息 //书的结构体 structBook{ unsignedintkey;//图书的书号 charbname[20];//书名 charwritter[20];//著者 unsignedintleft;//现存量 unsignedinttotal;//总存量 User*user;//借阅该书的人 }b[N];//定义书的信息 //B—树的存储结构 typedefBookKeyType; typedefstructBTNode{ intkeynum;//结点中关键字个数,即结点的大小 structBTNode*parent;//指向双亲结点 KeyTypekey[m+1];//关键字向量,号单元未用 structBTNode*ptr[m+1];//子树指针向量 }BTNode,*BTree; //查找结果的存储结构体 typedefstruct{ BTNode*pt;//指向找到的结点 inti;//1……m,在结点中的关键字序号 inttag;//B—树的查找结果类型 }Result; BTreeroot=NULL;//树根 //******************函数声明部分 //输入书的具体信息 voidInBookMess(KeyType&book); //输入书的关键字 voidInBookKey(KeyType&book); //显示书的具体信息,如果书存在就显示 voidShowBookMess(Bookbook); //显示一个结点中所包含的全部信息,显示单个结点 voidShowBTNode(BTreep); //显示,以层次的方法显示树的结点 voiddisplay(BTreeT); //复制关键字的信息 voidKeyTypeCopy(KeyType&bak,KeyTypek); //查找在某个结点中的位置 intSearch(BTreep,KeyTypeK); //查找 ResultSearchBTree(BTreeT,KeyTypeK); //插入 voidInsert(BTree&q,inti,KeyTypex,BTreeap); //分裂结点 voidsplit(BTree&q,ints,BTree&ap); //生成一个新的结点 voidNewRoot(BTree&T,BTreep,KeyTypex,BTreeap); //将书的信息插入到B-树中 StatusInsertBTree(BTree&T,KeyTypeK); //删除树结点 StatusDeleteBT(BTree&T,KeyTypek); //与右最左结点交换 voidexchange(BTree&T,inti); //用户借阅 StatusBorrowBook(BTreeT,KeyTypek); //注销对借阅者的登记,改变该书的显存量 StatusReturnBook(BTreeT,KeyTypek); voidtemp(BTreeT); voidsave(BTreep); /*************************************************/ voidsave(BTreep)//保存模块程序 { FILE*fp;//定义文件指针 if((fp=fopen(”book。 txt”,"wb”))==NULL)//判断文件的存在,若非空,将fp指向filename中记载的文件名的文件 { printf("创建文件失败! \n\n”);//打印出错提示 getchar(); return; } for(inti=1;i〈=p—>keynum;i++){ fprintf(fp,"%d%s%s%d%d\n”,p—〉key[i].key,p->key[i].bname,p—>key[i].writter,p->key[i].left,p-〉key[i].total); } fclose(fp);//关闭文件 } voidtemp(BTreeT) { inti; if(T){ save(T);//保存这个结点的全部值 for(i=0;i<=T—>keynum;i++){//使用递归的方法显示每个结点 if(T-〉ptr[i]){ temp(T—>ptr[i]); } } } } //读取文件 voidread() { FILE*fp,fp1;//定义文件指针 if((fp=fopen(”book。 txt”,"rb”))==NULL&&(fp=fopen(”user。 txt”,"rb”))==NULL)//判断文件的存在,若非空,将fp指向filename中记载的文件名的文件 { printf(”创建文件失败! \n\n”);//打印出错提示 getchar(); return; } for(inti=1;;i++)//读取文件 { if(fscanf(fp,"%d%s%s%d%d”,&b[i]。 key,&b[i].bname,&b[i].writter,&b[i]。 left,&b[i]。 total)==EOF) {break;} InsertBTree(root,b[i]); } fclose(fp);//关闭文件 } /**********************************************************/ //复制结点,将某个结点的值复制到另外一个值上 voidKeyTypeCopy(KeyType&bak,KeyTypek){ bak。 key=k。 key; strcpy(bak.bname,k。 bname); bak。 left=k。 left; bak.total=k.total; strcpy(bak。 writter,k。 writter); bak。 user=k.user; } //在一个结点中查找元素,返回结点的位置 intSearch(BTreep,KeyTypeK){ if(! p) return—1; inti=0; for(i=0;i〈p-〉keynum&&p-〉key[i+1].key〈=K.key;i++); returni; } //在m阶B树T上查找关键字K,返回结果(pt,i,tag) ResultSearchBTree(BTreeT,KeyTypeK){ BTreep,q; intfound,i; ResultR; //初始化变量 p=T; q=NULL; found=FALSE; i=0; //初始化,p指向待查结点,q指向p的双亲 while(p&&! found){ i=Search(p,K); //找到待查关键字 if(i〉0&&p—〉key[i].key==K.key) found=TRUE; else{ q=p; p=p—>ptr[i];//在另一个分支上查找 } } if(found){//查找成功 R。 pt=p; R.i=i; R。 tag=1; } else{//查找不成功 R。 pt=q; R.i=i; R。 tag=0; } //返回结果信息: K的位置(或插入位置) returnR; } //插入一条记录 voidInsert(BTree&q,inti,KeyTypex,BTreeap){ intn=q—〉keynum; for(intj=n;j〉i;j——){ KeyTypeCopy(q—>key[j+1],q-〉key[j]);//复制结点值 q->ptr[j+1]=q->ptr[j]; } KeyTypeCopy(q—〉key[i+1],x); q->ptr[i+1]=ap; if(ap) ap—〉parent=q; q—>keynum++; } //分离结点 voidsplit(BTree&q,ints,BTree&ap){ inti,j,n=q->keynum; ap=(BTree)malloc(sizeof(BTNode)); ap—>ptr[0]=q-〉ptr[s]; for(i=s+1,j=1;i<=n;i++,j++){ KeyTypeCopy(ap—>key[j],q->key[i]); ap—〉ptr[j]=q-〉ptr[i]; } ap—>keynum=n—s; ap—〉parent=q—〉parent; for(i=0;i〈=n-s;i++) if(ap-〉ptr[i]) ap—〉ptr[i]->parent=ap; q—〉keynum=s—1; } //生成一个新的树结点 voidNewRoot(BTree&T,BTreep,KeyTypex,BTreeap){ T=(BTree)malloc(sizeof(BTNode)); T->keynum=1;//设置当前结点的元素个数 T—〉ptr[0]=p;//设置左边结点的树根 T->ptr[1]=ap;//设置右边的树根 KeyTypeCopy(T->key[1],x);//将x元素的结点值复制到T的第一个元素中 //当孩子不空的时候就设置当前结点为孩子的双亲 if(p) p—>parent=T; if(ap) ap->parent=T; T-〉parent=NULL;//当前结点的双亲为空 } //返回false表示在原有结点上增加数量,返回true表示创建了一个新的结点 StatusInsertBTree(BTree&T,KeyTypeK){ //在m阶B树T上结点*q的key[i]与key[i+1]之间插入关键字K。 //若引起结点过大,则沿双亲链进行必要的结点分裂调整,使T仍是m阶B树。 BTreeap; Resultrs; BTreeq; inti; charaddnum; intfinished,needNewRoot,s; //T是空树(参数q初值为NULL) KeyTypex; //如果T结点为空就生成一个新的结点 if(! T){ NewRoot(T,NULL,K,NULL); } else{ //查找元素k在树中的位置 rs=SearchBTree(T,K); q=rs.pt;//查找到包含元素k的结点 i=rs.i;//元素k在树中的位置 if(rs。 tag==1){//判断该元素在树中是否存在 if(strcmp(q->key[i]。 bname,K。 bname)! =0){ printf("\n\t录入失败,原因: \n"); printf(".\t书号冲突,请重新为该书编号! \n\n”); printf(”\t已经存在书号为%d的书为: \n",q—>key[i]。 key); ShowBookMess(q—>key[i]); returnFALSE; } else { printf("\n\t该书已经存在! \n\n"); printf("\t是否增加其总量(y/n): ”); scanf("%s”,&addnum); if(addnum=='Y’||addnum=='y’){ q-〉key[i]。 total+=K。 total;//将总量增加 q-〉key[i].left+=K。 left;//将剩余量增加 printf(”\n\t增加总量后该书的信息如下\n”); //ShowBookMess(q->key[i]); } else{ printf("\n\t该书的信息如下: \n"); //ShowBookMess(q-〉key[i]); } ShowBookMess(q-〉key[i]); returnFALSE; } }//if x=K; ap=NULL; finished=needNewRoot=FALSE; while(! needNewRoot&&! finished){ Insert(q,i,x,ap);//插入结点 if(q->keynum〈m) finished=TRUE;//插入完成 else{//分裂结点*q s=(m+1)/2; split(q,s,ap); x=q—〉key[s]; if(q->parent){//在双亲结点*q中查找x的插入位置 q=q->parent; i=Search(q,x); } else needNewRoot=TRUE; }//else }//while if(needNewRoot)//根结点已分裂为结点*q和*ap NewRoot(T,q,x,ap);//生成新根结点*T,q和ap为子树指针 } returnOK; } //一个结点在双亲中的位置,返回其位置i intposition(BTreeT){ if(! T){ return0; } inti=0; if(T->parent){ while(i<=T->parent->keynum){ if(T==T->parent->ptr[i]) returni;//返回当前的位置 i++; } } return—1; } //调整树的结构 Statusfix(BTree&root,BTreep){ inti=position(p);//取得p在双亲中的位置 intmid=(m+1)/2-1;//要交换的临界点 BTreetemp=NULL; intk; if(i〉0&&root-〉ptr[i—1]—〉keynum〉mid){//当i大于零的时候就可以向左借 temp=root—>ptr[i-1];//比自己小的兄弟结点 p->keynum++;//增加一个结点 for(k=p-〉keynum;k>1;k--){ KeyTypeCopy(p-〉key[k],p-〉key[k—1]);//将前面的结点后移一位 } if(p—〉ptr[0]){ for(k=p-〉keynum;k>=1;k——){ p—〉ptr[k]=p->ptr[k-1];//将要移动的结点的子结点向后移动 } } KeyTypeCopy(p—〉key[1],root->key[i]);//将双亲的结点复制到根 KeyTypeCopy(root->key[i],temp-〉key[temp—>keynum]);//将小兄弟结点的最大的那个移动到双亲中 if(temp—>ptr[temp->keynum]){//将兄弟结点的子结点也复制过来 p—>ptr[0]=temp->ptr[temp—〉keynum]; temp—〉ptr[temp-〉keynum]-〉parent=p;//修改指向双亲的结点 temp-〉ptr[temp—>keynum]=NULL; } temp—>keynum--;//将左兄弟删除一个结点 returnOK; } if(i temp=root-〉ptr[i+1]; p—>keynum++;//增加结点的个数 KeyTypeCopy(p—>key[p—〉keynum],root->key[i+1]);//将根结点的值复制过来 KeyTypeCopy(root—〉key[i+1],temp—>key[1]);//将右兄弟的结点复制过来 for(k=1;k KeyTypeCopy(temp—〉key[k],temp—〉key[k+1]);//将后面的结点向前移动一位 } if(temp—〉ptr[0]){ p—〉ptr[p—〉keynum]=temp->ptr[0]; temp->ptr[0]—>parent=p;//修改指向双亲的结点 for(k=0;k〈temp—>keynum;k++){//将子结点向前移动 temp—>ptr[k]=temp—〉ptr[k+1]; } temp->ptr[k+1]=NULL;//将删除的结点的子结点置为空 } temp-〉keynum-—;//将右兄弟删除一个结点 returnOK; } returnFALSE; } //合并结点 Statuscombine(BTree&root,BTree&p){ intk,i=position(p);//取得p在双亲中的位置 intmid=(m+1)/2-1;//交换的条件 BTreep2; if(i==0){//如果是第一个位置 i=1; p2=root—〉ptr[i]; p—〉keynum++;//增加一个结点 KeyTypeCopy(p->key[p—>keynum],root->key[i]);//将双亲的结点复制下来 if(p2—>ptr[0]){
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 图书 管理 系统