学校数据结构的课程实验之一。

用到的数据结构:B-树

基本功能:对虚拟书库的图书进行查看、增加、删除、修改。

主函数:

 #include <iostream>
#include "Library.h"
using namespace std;
int main()
{
Library myLib=Library("books.txt");
char choice='y';
while(choice=='y')
{
cout << "请选择操作"<<endl;
cout << "--------------------------------" << endl;
cout << "1----新书入库" << endl;
cout << "2----查看库存" << endl;
cout << "3----借阅" << endl;
cout << "4----归还" << endl;
cout << "5----删除旧书" << endl;
cout << "6----修改图书信息" << endl;
cout << "--------------------------------" << endl;
int option;
cin >> option;
switch (option)
{
case : myLib.add(); break;
case : myLib.display(); break;
case : myLib.lend(); break;
case : myLib.back(); break;
case : myLib.remove(); break;
case : myLib.change(); break;
}
cout << "继续吗?[y/n]";
cin >> choice;
}
cout << "是否保存修改?[y/n]";
cin >> choice;
if (choice == 'y')
myLib.save("books.txt");//需要保存时保存文件
return ;
}

图书馆类:

 #include <fstream>
#include <string>
#include "B_tree.h"
using namespace std; struct Book
{
int number;
string name;
string introduction;
unsigned left;
Book(){}
Book(int num) :number(num), name(""), introduction(""), left(){}//只有编号的初始化
Book(int num, string nam,string intro, unsigned lef)//完整初始化
:number(num),name(nam),introduction(intro),left(lef){}
void print()//显示信息
{
cout << "-------------------------------" << endl;
cout << "这本书的信息如下:" << endl;
cout << "编号: " << number << endl;
cout << "书名: " << name << endl;
cout << "简介: " << introduction << endl;
cout << "剩余数量: " << left << endl;
cout << "-------------------------------" << endl;
}
bool operator==(const Book &b) const//重载关系运算符
{
if(this->number == b.number) return true;//编号等即命中
else return false;
}
bool operator<(const Book &b) const
{
if (this->number < b.number) return true;
else return false;
}
bool operator>(const Book &b) const
{
if (this->number > b.number) return true;
else return false;
}
};
ofstream outFile;//输出流 class Library
{
private:
B_tree<Book,> books;
unsigned total;
static void readBook(Book &aBook)//写一本书的内容(一定要是静态的)
{
outFile<<aBook.number<<endl;
outFile<<aBook.name<<endl;
outFile<<aBook.introduction<<endl;
outFile << aBook.left << endl;
}
void readFile(const char filename[])//读文件
{
total = ;
ifstream inFile;
inFile.open(filename);
char trying;
while(inFile.is_open() && !inFile.eof())
{
//先试探是否为结束符
inFile >> trying;
if (trying == '#') break;
else
{
inFile.putback(trying);
int number;
inFile>>number;
string name;
inFile>>name;
string introduction;
inFile>>introduction;
unsigned left;
inFile>>left;
Book aBook=Book(number,name,introduction,left);
aBook.print();//显示这本书的信息
books.insert(aBook);
total+=left;
}
}
cout << "库存共有图书" << total << "本"<<endl;
inFile.close();
}
void writeFile(const char filename[])//写文件
{
outFile.open(filename);
books.traverse(readBook);
outFile << '#';//此处必须有一个结束标识符
outFile.close();
}
Book search(int num)//以编号为依据进行查找
{
Book se_book(num);
books.search_tree(se_book);
return se_book;
}
static void print(Book &aBook)//显示信息(必须是静态的)
{
cout << "-------------------------------" << endl;
cout << "这本书的信息如下:" << endl;
cout << "编号: " << aBook.number << endl;
cout << "书名: " << aBook.name << endl;
cout << "简介: " << aBook.introduction << endl;
cout << "剩余数量: " << aBook.left << endl;
cout << "-------------------------------" << endl;
}
public:
Library(const char filename[])
{
cout << "这是现在的库存信息:" << endl;
readFile(filename);
}
void add()//增加图书
{
cout << "请输入图书信息(编号 书名 简介 数量)" << endl;
int num;
string name;
string introduction;
unsigned left;
cin >> num >> name >> introduction >> left;
Book new_book = Book(num, name, introduction, left);
books.insert(new_book);
cout << "这本书已入库,信息如下:" << endl;
new_book.print();
total += left;
}
void display()//查看库存
{
cout << "这是现在的库存信息:" << endl;
books.traverse(print);
cout << "库存共有图书" << total << "本" << endl;
}
void remove()//删除
{
cout << "请输入要删除的图书编号:";
int num;
cin >> num;
Book &old_book =search(num);//通过编号找到这本书的记录
cout << "您即将删除这本书的所有信息:" << endl;
old_book.print();
cout << "确定要删除吗?[y/n]";
char choice;
cin >> choice;
if (choice == 'y')
{
books.remove(old_book);//删除这本书的记录
cout << "编号为" << num << "的书已成功从库中删除" << endl;
total--;
}
}
void lend()//借出
{
cout << "请输入要借出的图书编号:";
int num;
cin >> num;
Book &old_book = search(num);//通过编号找到这本书的记录
old_book.left--;
cout << "编号为" << num << "的图书已借出1本,下面是这本书的现存信息:" << endl;
old_book.print();
total--;
}
void change()//修改(先删除再添加)
{
cout << "请输入要修改的图书编号:";
int num;
cin >> num;
Book &old_book = search(num);
cout << "这是这本书的当前信息:" << endl;
old_book.print();//显示这本书之前的信息
books.remove(old_book);
cout << "请输入修改后的图书信息(编号 书名 简介 数量)" << endl;
string name;
string introduction;
unsigned left;
cin >> num >> name >> introduction >> left;
Book new_book = Book(num, name, introduction, left);
books.insert(new_book);
cout << "这本书的信息已修改为:" << endl;
new_book.print();
}
void back()//归还
{
cout << "请输入要归还的图书编号:";
int num;
cin >> num;
Book &old_book = search(num);//通过编号找到这本书的记录
old_book.left++;
cout << "编号为" << num << "的图书已归还,下面是这本书的现存信息:" << endl;
old_book.print();
total++;
}
void save(const char filename[])
{
writeFile(filename);
}
};

Library.h

B-树的实现参考了经典教材"Data Structures and Program Design in C++" Robert L. Kruse, Alexander J. Ryba 高等教育出版社-影印版,代码如下:

 #include <iostream>
using namespace std;
enum Error_code
{
success, not_present, overflow, duplicate_error
}; template <class Record, int order>//阶数(分支数)
struct B_node
{
int count;//成员数
Record data[order-];
B_node<Record,order> *branch[order];
B_node(){count=;}
}; template <class Record, int order>
class B_tree
{
public:
B_tree(){root=NULL;}
Error_code search_tree(Record &target)
{
return recursive_search_tree(root,target);
}
Error_code insert(const Record &new_entry)
{
Record median;
B_node<Record,order> *right_branch, *new_root;
Error_code result=push_down(root,new_entry,median,right_branch);
if(result==overflow)
{
new_root=new B_node<Record,order>;
new_root->count=;
new_root->data[]=median;
new_root->branch[]=root;
new_root->branch[]=right_branch;
root=new_root;
result=success;
}
return result;
}
Error_code remove(const Record &target)
{
Error_code result;
result=recursive_remove(root, target);
if(root != NULL && root->count==)
{
B_node<Record,order> *old_root=root;
root=root->branch[];
delete old_root;
}
return result;
}
void traverse(void (*visit)(Record &))
{
recursie_traverse(root,visit);
}
private:
B_node<Record, order> *root;
void recursie_traverse(B_node<Record,order> *current, void (*visit)(Record &))
{
if(current!=NULL)
{
for(int i=; i<current->count; i++)
(*visit)(current->data[i]);
for(int i=; i<current->count+; i++)
recursie_traverse(current->branch[i], visit);
}
}
Error_code search_node(B_node<Record,order> *current, const Record &target, int &position) const
{
position=;
while(position < current->count && (target > current->data[position]))
position++;
if(position < current->count && target == current->data[position])
return success;
else return not_present;
}
Error_code recursive_search_tree(B_node<Record,order> *current, Record &target)
{
Error_code result=not_present;
int position;
if(current != NULL)
{
result=search_node(current,target,position);
if(result==not_present)
result=recursive_search_tree(current->branch[position],target);
else
target=current->data[position];
}
return result;
}
void split_node(B_node<Record,order> *current, const Record &extra_entry,
B_node<Record,order> *extra_branch, int position,
B_node<Record,order>*&right_half, Record &median)
{
right_half=new B_node<Record,order>;
int mid=order/;
if(position <= mid)
{
for(int i=mid; i<order-; i++)
{
right_half->data[i-mid]=current->data[i];
right_half->branch[i+-mid]=current->branch[i+];
}
current->count=mid;
right_half->count=order--mid;
push_in(current,extra_entry,extra_branch,position);
}
else
{
mid++;
for(int i=mid; i<order-; i++)
{
right_half->data[i-mid]=current->data[i];
right_half->branch[i+-mid]=current->branch[i+];
}
current->count=mid;
right_half->count=order--mid;
push_in(right_half,extra_entry,extra_branch,position-mid);
}
median=current->data[current->count-];
right_half->branch[]=current->branch[current->count];
current->count--;
}
void push_in(B_node<Record,order> *current, const Record &entry,
B_node<Record,order> *right_branch, int position)
{
for(int i=current->count; i>position; i--)
{
current->data[i]=current->data[i-];
current->branch[i+]=current->branch[i];
}
current->data[position]=entry;
current->branch[position+]=right_branch;
current->count++;
}
Error_code push_down(B_node<Record,order> *current, const Record &new_entry,
Record &median, B_node<Record,order>*&right_branch)
{
Error_code result;
int position;
if(current==NULL)
{
median=new_entry;
right_branch=NULL;
result=overflow;
}
else
{
if(search_node(current,new_entry,position)==success)
result=duplicate_error;
else
{
Record extra_entry;
B_node<Record,order> *extra_branch;
result=push_down(current->branch[position],new_entry,
extra_entry,extra_branch);
if(result==overflow)
{
if(current->count < order-)
{
result=success;
push_in(current,extra_entry,extra_branch,position);
}
else
split_node(current,extra_entry,extra_branch,position,
right_branch,median);
}
}
}
return result;
}
void restore(B_node<Record,order> *current, int position)
{
if(position==current->count)
if(current->branch[position-]->count > (order-)/)
move_right(current,position-);
else
combine(current,position);
else if(position==)
if(current->branch[]->count > (order-)/)
move_left(current,);
else
combine(current,);
else
if(current->branch[position-]->count > (order-)/)
move_right(current,position-);
else if(current->branch[position+]->count > (order-)/)
move_left(current,position+);
else combine(current,position);
}
void move_left(B_node<Record,order> *current, int position)
{
B_node<Record,order> *left_branch=current->branch[position-],
*right_branch=current->branch[position];
left_branch->data[left_branch->count]=current->data[position-];
left_branch->branch[++left_branch->count]=right_branch->branch[];
current->data[position-]=right_branch->data[];
right_branch->count--;
for(int i=; i<right_branch->count; i++)
{
right_branch->data[i]=right_branch->data[i+];
right_branch->branch[i]=right_branch->branch[i+];
}
right_branch->branch[right_branch->count]=
right_branch->branch[right_branch->count+];
}
void move_right(B_node<Record,order> *current, int position)
{
B_node<Record,order> *right_branch=current->branch[position+],
*left_branch=current->branch[position];
right_branch->branch[right_branch->count+]=
right_branch->branch[right_branch->count];
for(int i=right_branch->count; i>; i--)
{
right_branch->data[i]=right_branch->data[i-];
right_branch->branch[i]=right_branch->branch[i-];
}
right_branch->count++;
right_branch->data[]=current->data[position];
right_branch->branch[]=left_branch->branch[left_branch->count--];
current->data[position]=left_branch->data[left_branch->count];
}
void combine(B_node<Record,order> *current, int position)
{
int i;
B_node<Record,order> *left_branch=current->branch[position-],
*right_branch=current->branch[position];
left_branch->data[left_branch->count]=current->data[position-];
left_branch->branch[++left_branch->count]=right_branch->branch[];
for(i=; i<right_branch->count; i++)
{
left_branch->data[left_branch->count]=right_branch->data[i];
left_branch->branch[++left_branch->count]=right_branch->branch[i+];
}
current->count--;
for(i=position-; i<current->count; i++)
{
current->data[i]=current->data[i+];
current->branch[i+]=current->branch[i+];
}
delete right_branch;
}
void copy_in_predecessor(B_node<Record,order> *current, int position)
{
B_node<Record,order> *leaf=current->branch[position];
while(leaf->branch[leaf->count] != NULL)
leaf=leaf->branch[leaf->count];
current->data[position]=leaf->data[leaf->count-];
}
void remove_data(B_node<Record,order> *current, int position)
{
for(int i=position; i<current->count-; i++)
current->data[i]=current->data[i+];
current->count--;
}
Error_code recursive_remove(B_node<Record,order> *current, const Record &target)
{
Error_code result;
int position;
if(current==NULL) result=not_present;
else
{
if(search_node(current,target,position)==success)
{
result=success;
if(current->branch[position]!=NULL)
{
copy_in_predecessor(current,position);
recursive_remove(current->branch[position],current->data[position]);
}
else
remove_data(current,position);
}
else result=recursive_remove(current->branch[position],target);
if(current->branch[position]!=NULL)
if(current->branch[position]->count < (order-)/)
restore(current,position);
}
return result;
}
};

B_tree.h

用B-树实现虚拟图书管理系统的更多相关文章

  1. Vue.js—实现图书管理系统

      前  言 今天我们主要一起来学习一个新框架的使用--Vue.js,之前我们也讲过AngularJS是如何使用的,而今天要讲的Vue.js的语法和AngularJS很相似,因为 AngularJS ...

  2. Linux-基础学习(四)-部署图书管理系统项目

    部署图书管理项目需要以下软件 项目文件(django项目文件夹) 数据库文件(django项目对应的数据库文件) centos7(linux本体) nginx(反向代理以及静态文件收集) uWSGI( ...

  3. 基于Java swing+mysql+eclipse的【图书管理系统】

    本项目为Java swing项目,在工作环境中基本使用不到,但是很多学校把这个当做编程入门的项目来做,故分享出本项目供初学者参考. CSDN赞助下载:https://download.csdn.net ...

  4. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  5. 基于jsp+servlet图书管理系统之后台万能模板

    前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...

  6. [入门级] 基于 visual studio 2010 mvc4 的图书管理系统开发初步 (二)

    [入门级] 基于 visual studio 2010 mvc4 的图书管理系统开发初步 (二) Date  周六 10 一月 2015 By 钟谢伟 Category website develop ...

  7. 基于TXT文本的简单图书管理系统

    1 ////////////////////////////////////////////////////////////////////////////////////// //SqList.h ...

  8. struts2+hibernate 项目实战:图书管理系统

    经典项目,练手必备. 图书管理系统 需求分析(大致,并不专业):1.需要有用户管理: 1.1 用户注册: 1.2 用户登录: 1.3 用户信息修改: 1.4 用户修改密码: 2.需要有书本管理: 2. ...

  9. 图书管理系统——APP平台开发

    http://www.w3school.com.cn/php/ 初步计划采用PHP 开发网站. 一定要独立建立一套图书管理系统, 尤其唯一性质的概念,整合,甚至中英文图书概念的而整合.一本书一个页. ...

随机推荐

  1. Sqrt(x) 解答

    Question Implement int sqrt(int x). Compute and return the square root of x. Solution 1 -- O(log n) ...

  2. hdu5772-String problem(最大权闭合子图问题)

    解析: 多校标答 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分)第二类:原串中的n个点每个点拆出一个点,第i个点权值为 –a[s[i]] ...

  3. 《数据通信与网络》笔记--IPSec

    1.IP层的安全:IPSec IP层安全(IP security,IPsec)是由因特网工程任务组(IETF)设计用来为IP层的分组提供安全的一组协议.IPsec帮助 生成经过鉴别的与安全的IP层的分 ...

  4. AsyncTask实现登录功能,上传图片,get,post

    提交成功时,从服务器端返回数据“load success” 用户名.密码正确后成功登录,并且在服务器端的文件保存目录上看到了从客户端上传的图片. 客户端代码: MainActivity.java im ...

  5. 关于vi不正常退出产生的swp文件

    关于vi不正常退出产生的swp文件   非正常关闭vi编辑器时会生成一个.swp文件 关于swp文件 使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vi就会生成这么 ...

  6. 无法登陆mysql服务器

    解决 .#2002 无法登录 MySQL 服务器 将config.sample.inc.php复制成config.inc.php 出现这个错误,表示没有连接到数据库.修改config.inc.php文 ...

  7. CPU性能测试

    用计算圆周率的办法来测试cpu性能 4*a(1) 是 bc 主動提供的一個計算 pi 的函數,至於 scale 就是要 bc 計算幾個小數點下位數的意思.當 scale 的數值越大, 代表 pi 要被 ...

  8. 自定义上传按钮 <input type="file" name = "file"/> (将file隐藏在button下)

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  9. NSBundle 类

    NSBundle NSBundle继承于NSObject,NSBundle是一个程序包,其中包含了程序会使用的资源(图像,声音,编辑好的代码,nib文件). 一. 初始化NSBundle + (ins ...

  10. (原)ubuntu16中简单的使用google的protobuf

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5804395.html 参考网址: http://www.cnblogs.com/luosongchao ...