目录:
如果觉得这篇文章有用的话,麻烦大家 点个赞 支持一下!!
一、实现的设计要求
图书管理基本业务活动包括:对一本书的采编入库、清除库存、借阅和归还等等。试设计一个图书管理系统,将上述业务活动借助于计算机系统完成。
1、基本要求
(1)每种书的登记内容至少包括书号、书名、著者、出版社、现存量和总库存量等六项。
(2)作为演示系统,不必使用文件,全部数据可以都在内存存放。但是由于上述四项基本业务活动都是通过书号(即关键字)进行的,所以要用B树(2-3树)对书号建立索引,以获得高效率。
(3)系统应实现的操作及其功能定义如下:
①采编入库:新购入一种书,经分类和确定书号之后登记到图书账目中去。如果这种书在帐中已有,则只将总库存量增加。
②清除库存:某种书已无保留价值,将它从图书账目中注销。
③借阅:如果一种书的现存量大于零,则借出一本,登记借阅者的图书证号和归还期限。
④归还:注销对借阅者的登记,改变该书的现存量。
⑤显示:以凹入表的形式显示B树。这个操作是为了调试和维护的目的而设置的。下列B树的打印格式如下所示:
2、额外选做要求
(1) 增加列出某种书状态的操作。状态信息除了包括这种书记录的全部信息外还包括最早到期(包括已逾期)的借阅者证号,日期可用整数实现,以求简化。
二、项目文件管理
(1)在头文件BTreeBook.h里面定义了B树的有关结构及其接口和图书管理系统有关的操作接口
(2)在源文件BTreeBook.cpp里面实现了头文件BTreeBook.h里面的函数接口。(3)在main.cpp里面定义了主函数,并且把头文件BTreeBook.h包含进来即可调用有关接口。
三、完整代码
1、实现的接口
图书管理系统的操作接口:
void InsertBook(BTree &t, KeyType key, result r, char *bookname, char *writername, char *bookpress, int num); //采编入库
void DeleteBook(BTree &t, KeyType key); //清除库存
void BorrowBook(result r,int number,char *name); //借阅图书
Status ReturnBook(result r, int number, char *name); //归还图书
void ShowBookAll(BTree t, KeyType key); //查看某种图书的信息(包括借阅者)
以上接口需要调用的函数:
void ShowBook(BTree t, KeyType key); //输出某本书的信息(不包括借阅者)
void addBook(BTree t, KeyType key, int num); //添加某本书的数量
Status emtyBook(BTree q, int i); //检查某本书的现存量是否大于0
B树的操作接口:
void SearchBTree(BTree t, KeyType k, result &r); //查找
void InsertBTree(BTree &t, KeyType k, BTree q, int i,BookType *book); //插入
void DeleteBTree(BTree &t, KeyType key); //删除
void InitBTree(BTree &t); //创建
void PrintBTree(BTree t); //遍历打印输出
void Traverse(BTree t, int k);//递归遍历
int SearchBTNode(BTree p, KeyType k);//在结点p中查找关键字k
void split(BTree &q, int s, BTree &ap);//将q结点分裂成两个结点,前一半留在原节点,后一半留在ap指向的新结点
void newRoot(BTree &t, BTree p, KeyType x, BTree ap,BookType *book);//生成新的根结点
void Insert(BTree &q, int i, KeyType x, BTree ap,BookType *book);//关键字x和新结点指针ap分别插入到q->key[i]和q->ptr[i]
int BTNodeDelete(BTNode *p, KeyType key);//在结点p中删除关键字key
int FindBTNode(BTNode *p, KeyType k, int &i);//在结点p中查找关键字k,返回位置i
void Remove(BTNode *p, int i);//在结点p中删除关键字key[i]和其孩子结点ptr[i]
void Substitution(BTNode *p, int i);//在结点p中查找被删除的关键字key[i]的替代叶子结点
void AdjustBTree(BTNode *p, int i);//在结点p中删除关键字key[i]后调整B树
void MoveRight(BTNode *p, int i);//将双亲结点p中的最后一个关键字移入右结点q中,将左结点aq中的最后一个关键字移入双亲结点p中
void MoveLeft(BTNode *p, int i);//将双亲结点p中的第一个关键字移入结点aq中,将结点q中的第一个关键字移入双亲结点p中
void Combine(BTNode *p, int i);//将双亲结点p、右结点q合并入左结点aq,并调整双亲结点p中的剩余关键字的位置
2、头文件 BTreeBook.h 全部代码
#pragma once
#define m 3 //B树的阶
#define TRUE 1;
#define FALSE 0;
#define OK 1;
#define ERROR 0;
#define OVERFLOW -1;
typedef int Status;
typedef int KeyType; //书号BookId类型
typedef struct ReaderType{
int readerId; //读者图书证号
char name[20]; //读者姓名
int time; //归还时间
struct ReaderType * next;
}ReaderType; //读者类型
typedef struct {
char bookName[30]; //书名
char writerName[20]; //作者
char bookPress[30]; //出版社
int booknumNow; //现存量
int booknumAll; //总库存量
ReaderType * reader;
}BookType; //书本类型
typedef struct BTNode {
int keynum; //结点当前的关键字个数
KeyType key[m + 1]; //关键字数组,key[0]未用
struct BTNode * parent; //双亲结点指针
struct BTNode * ptr[m + 1]; //孩子结点指针数组
BookType * book[m + 1]; //书本指针数组,bkptr[0]未用
}BTNode, *BTree; //B树的结点和指针类型
typedef struct {
BTree pt; //指向找到的结点
int i; //结点中的关键字位序
int tag; //1为成功,0为失败
}result; //Search结果类型
//图书管理的操作接口
void InsertBook(BTree &t, KeyType key, result r, char *bookname, char *writername, char *bookpress, int num); //采编入库
void DeleteBook(BTree &t, KeyType key); //清除库存
void BorrowBook(result r,int number,char *name); //借阅图书
Status ReturnBook(result r, int number, char *name); //归还图书
void ShowBookAll(BTree t, KeyType key); //查看某种图书的信息(包括借阅者)
void ShowBook(BTree t, KeyType key); //输出某本书的信息
void addBook(BTree t, KeyType key, int num); //添加某本书的数量
Status emtyBook(BTree q, int i); //检查某本书的现存量是否大于0
//B树的操作接口
void SearchBTree(BTree t, KeyType k, result &r); //查找
void InsertBTree(BTree &t, KeyType k, BTree q, int i,BookType *book); //插入
void DeleteBTree(BTree &t, KeyType key); //删除
void InitBTree(BTree &t); //创建
void PrintBTree(BTree t); //遍历打印输出
void Traverse(BTree t, int k);//递归遍历
int SearchBTNode(BTree p, KeyType k);//在结点p中查找关键字k
void split(BTree &q, int s, BTree &ap);//将q结点分裂成两个结点,前一半留在原节点,后一半留在ap指向的新结点
void newRoot(BTree &t, BTree p, KeyType x, BTree ap,BookType *book);//生成新的根结点
void Insert(BTree &q, int i, KeyType x, BTree ap,BookType *book);//关键字x和新结点指针ap分别插入到q->key[i]和q->ptr[i]
int BTNodeDelete(BTNode *p, KeyType key);//在结点p中删除关键字key
int FindBTNode(BTNode *p, KeyType k, int &i);//在结点p中查找关键字k,返回位置i
void Remove(BTNode *p, int i);//在结点p中删除关键字key[i]和其孩子结点ptr[i]
void Substitution(BTNode *p, int i);//在结点p中查找被删除的关键字key[i]的替代叶子结点
void AdjustBTree(BTNode *p, int i);//在结点p中删除关键字key[i]后调整B树
void MoveRight(BTNode *p, int i);//将双亲结点p中的最后一个关键字移入右结点q中,将左结点aq中的最后一个关键字移入双亲结点p中
void MoveLeft(BTNode *p, int i);//将双亲结点p中的第一个关键字移入结点aq中,将结点q中的第一个关键字移入双亲结点p中
void Combine(BTNode *p, int i);//将双亲结点p、右结点q合并入左结点aq,并调整双亲结点p中的剩余关键字的位置
3、源文件 BTreeBook.cpp 全部代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"BTreeBook.h"
//图书管理的操作实现
void InsertBook(BTree &t,KeyType key, result r,char *bookname,char *writername,char *bookpress,int num) {
BookType *book;
book = (BookType *)malloc(sizeof(BookType));
strcpy_s(book->bookName, bookname);
strcpy_s(book->writerName, writername);
strcpy_s(book->bookPress, bookpress);
book->booknumAll = num;
book->booknumNow = num;
book->reader = NULL;
if(r.tag==0)
InsertBTree(t, key, r.pt, r.i, book);
}//采编入库
void DeleteBook(BTree &t, KeyType key) {
DeleteBTree(t, key);
}//清除库存
void BorrowBook(result r,int number,char *name) {
ReaderType *reader;
reader = (ReaderType *)malloc(sizeof(ReaderType));
strcpy_s(reader->name, name);
reader->readerId = number;
reader->time = 50;
ReaderType *q;
q = r.pt->book[r.i]->reader;
if (q == NULL) {
r.pt->book[r.i]->reader = reader;
reader->next = NULL;
}
else {
reader->next = r.pt->book[r.i]->reader;
r.pt->book[r.i]->reader = reader;
}
r.pt->book[r.i]->booknumNow--;
}//借阅图书
Status ReturnBook(result r, int number, char *name) {
ReaderType *q,*p;
q = r.pt->book[r.i]->reader;
p = q;
while (q != NULL && (q->readerId != number || strcmp(q->name,name))) {
p = q;
q = q->next;
}
if (q == NULL) {
return FALSE;
}
else {
if (q == r.pt->book[r.i]->reader)
r.pt->book[r.i]->reader = q->next;
else
p->next = q->next;
free(q);
r.pt->book[r