图书信息管理系统
把图书表抽象成一个线性表,每本图书(包括ISBN、书名、定价)作为线性表中的一个数据元素。在图书信息管理系统中要求实现查找、插入、删除、修改、排序和计数共6个功能。步骤和要求如下:(以顺序或链式存储结构均可,下面以链式存储结构为例)
(1)定义存储图书的结点结构
#define MAXSIZE 10000 //图书表可能达到的最大长度
typedef struct //图书信息定义
{
char no[20]; //图书ISBN
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct LNode
{
Book data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode,*LinkList //图书表的链式存储结构类型为LinkList
(2)在图书表的链式存储结构类型LinkList之上实现图书的
查找、插入、删除、修改、排序和计数的函数。
(3)在main函数中调用以上函数实现图书管理系统的各种功能。
算法描述:
查找功能算法描述:
函数名: Locate(string x)
输入: string x
功能: 根据信息在链表中查找该书在链表中的位置
输出: 查找到就输出其信息
(2)插入功能算法描述:
函数名: Insert( )
输入: 无
功能: 在链表最后插入一本书的信息进入链表
输出: 无
(3)删除功能算法描述:
函数名: Delete(int i)
输入: 整数i
功能: 删除序号为i的结点
输出: 无
(4)修改功能算法描述:
函数名: MoDify(string x)
输入: string x
功能: 修改信息
输出: 无
(5)排序功能算法描述:
函数名: Sort()
输入: 无
功能: 对链表内所有的内容进行归纳排序
输出: 无
(6)计数功能算法描述:
函数名: Length()
输入: 无
功能: 计算链表内结点个数
输出: 结点个数
算法实现步骤:
(1)查找功能算法实现步骤:
定义函数时设置一个string类型的参数,该参数由用户输入,是用户想要查找的书籍的特征值,比如书名和书的编码,然后传递到函数中,在函数中从头节点开始向尾节点遍历,如果其中某一节点内存储的书籍信息与之相符,则查找到目标书籍,然后break跳出循环。如果整个链表遍历完仍找不到就输出系统中不存在该书
(2)插入功能算法实现步骤:
该功能简化版就是在链表末端再加一个节点,这样用户只需要向系统中输入书籍的信息即可。
(3)删除功能算法实现步骤:
用户输入想要删除第几本书,输入其编号,然后函数内从头节点向尾节点遍历,直到查找到该书所在的节点的上一个节点,然后该节点的指针域指向下一个节点的指针域所指向的区域,delete该节点,这样就完成删除
(4)修改功能算法实现步骤:
需要用户输入需要修改的书籍的相关信息,比如书的名称,或书的号码(ISBN),然后从头节点向尾节点遍历,访问每个节点时将节点中的存储的信息与用户输入的信息对比,如果相同即找到对应的书籍,反之一直遍历到尾节点。找到匹配的节点后,然后对节点的信息进行修改。
(5)排序功能算法实现步骤:
对图书的排序,因为不同种类的书籍之间最大不同就是书籍的种类不同,所以这里使用pair的second存书籍的类型,用first存书籍的数量,排序就是对同种书籍的数量进行排序,从低到高排序,这样排序也等于对书籍进行了收纳,结合网上的资料可知,图书馆的书籍是同类书籍放在一起,而不是简单的对书籍的名称或者编码进行排序。
(6)计数功能实现步骤:
本功能就是对链表进行一次遍历,统计节点数量,在显示统计的数量
#include<bits/stdc++.h>
#include <windows.h>
#define MAXSIZE 1e5
using namespace std;
typedef struct //图书信息定义
{
string no; //图书ISBN 书号
string name; //图书名字
string price; //图书价格
string type; //图书类型
} Book;
typedef struct LNode
{
Book data; //结点的数据域
struct LNode *next; //结点的指针域
} LNode; //图书表的链式存储结构类型为LinkList
class LinkList
{
public:
LinkList( );
~LinkList( ); //析构函数
int Length( ); //求单链表的长度
int Empety(); //判断是否为空
void Locate(string x); //按值查找。查找值为x的元素序号
void Insert( ); //插入操作,第i个位置插入值为x的结点
void Delete(int i); //删除操作,删除第i个结点
void Sort();//排序
void MoDify(string x);//修改
LNode *first; //单链表的头指针
};
/***************
函数名: LinkList()
输入: 无
功能: 生成头节点
输出: 无
***************/
LinkList::LinkList()
{
first = new LNode; //生成头结点
first->next = nullptr; //头结点的指针域置空
}
/***************
函数名: ~LinkList()
输入: 无
功能: 释放空间
输出: 无
***************/
LinkList::~LinkList()
{
LNode*q = NULL;
while (first != NULL) //释放单链表的每一个结点的存储空间
{
q = first; //暂存被释放结点
first = first->next; // first指向被释放结点的下一个结点
delete q;
}
}
/***************
函数名: Length()
输入: 无
功能: 计算链表内结点个数
输出: 结点个数
***************/
int LinkList::Length()
{
LNode*p = first->next; //工作指针p初始化为开始接点
int count = 0; //累加器count初始化
while (p != nullptr)
{
p = p->next;
count++;
}
return count; //注意count的初始化和返回值之间的关系
}
/****************
函数名: Empety()
输入: 无
功能: 判断链表是否为空
输出: 返回1,表示为空,返回0,表示不为空
***************/
int LinkList::Empety()
{
if(first->next == nullptr)
return 1;
else
return 0;
}
/***************
函数名: Locate(string x)
输入: string x
功能: 根据信息在链表中查找
该书在链表中的位置
输出: 查找到就输出其信息
***************/
void LinkList:: Locate(string x)
{
LNode*p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr)
{
if (p->data.name == x|| p->data.no == x)//查找成功,结束函数并返回序号
{
cout << " 在系统中的序号是 : " << count << endl;
cout << " 书名为:" << p->data.name << endl;
cout << " 价格是:" << p->data.price << endl;
cout << " 书码为:" << p->data.no << endl;
system("pause");
break;
}
p = p->next;
count++;
}
if(p==nullptr)
{
cout << " 没有这本书" << endl;
cout << " 自动退出" << endl;
}
}
/***************
函数名: Insert( )
输入: 无
功能: 在链表最后插入一本书的信息进入链表
输出: 无
***************/
void LinkList :: Insert( )
{
string t1 = "1";
string t2 = "2";
string t3;
while(1)
{
cout <<" --------------------------插入界面--------------------------"<< endl;
cout <<" | 1 插入 |"<< endl;
cout <<" | 2 退出 |"<< endl;
cout << " 功能简介 :输入 1 选择插入功能,插入功能的作用是向系统添加书的三个主要信息" << endl;
cout << " 1.ISBN码, 2.书的名字,3.书的价格" << endl;
cout << " 输入 1 后便是选择此功能,后续会有消息提醒来一步步辅助你填入这些信息"<<endl;
cout << " 输入 2 退出插入界面,其他数字或符号为无效命令" << endl;
cout <<endl << endl << endl;
cout << " 请输入你选择的功能<1 or 2> : "<<endl;
cout <<" ";
cin >> t3 ;
if(t3 == t1)
{
Book x;
cout <<" 请输入书的 ISBN 号码:"; cin >> x.no;
cout <<" 请输入书的 名字 : "; cin >> x.name;
cout <<" 请输入书的 价格 :"; cin >> x.price;
cout <<" 请输入书的 类型 :"; cin >> x.type;
LNode *p = first, *s = nullptr ; //工作指针p初始化
int count = 0;
while (p->next != nullptr) //查找最后一个结点
{
p = p->next; //工作指针p后移
}
if (p == nullptr) cout << " 插入失败" << endl;//没有找到第i – 1个结点
else {
s = new LNode; s->data = x; //申请结点s,数据域为x
s->next = p->next; p->next = s; //将结点s插入到结点p之后
}
}
else if(t3 == t2){
cout << " 再见" << endl;
break;
}
else
{
cout << " 输入的指令错误 ,请重新输入" << endl;
cout <<" ";
cin >> t3 ;
}
}
}
/***************
函数名: Delete(int i)
输入: 整数i
功能: 删除序号为i的结点
输出: 无
***************/
void LinkList :: Delete(int i)
{
LNode *p = first, *q = nullptr; //工作指针p指向头结点
int count = 0;
while (p != nullptr && count < i - 1) //查找第i-1个结点
{
p = p->next;
count++;
}
if (p == nullptr || p->next == nullptr) //结点p不存在或p的后继结点不存在
cout << " 该书不存在" << endl;
else {
q = p->next; //暂存被删结点
cout << " 书号码是:" << q->data.no <<endl;
cout << " 书的名字:" << q->data.name<< endl;
p->next = q->next; //摘链
delete q;
system("pause");
}
}
/***************
函数名: Sort()
输入: 无
功能: 对链表内所有的内容进行归纳排序
输出: 无
***************/
void LinkList::Sort()
{
LNode*q = NULL;
LNode*p = first->next;
pair<int ,string> s[10000];
s[0].first = 1;
s[0].second = p->data.type;
p=p->next;
int idx = 1;
bool st = 1;
while (p != NULL) //释放单链表的每一个结点的存储空间
{
for(int i = 0; i < idx; i ++)
{
if(s[i].second == p->data.type)
{
s[i].first++;
st = 0;
break;
}
}
if(st)
{
s[idx].second = p->data.type;
s[idx++].first = 1;
}
p = p->next; // first指向被释放结点的下一个结点
}
sort(s,s+idx);
for(int i = 0; i < idx ; i ++ )
{
cout <<" "<< s[i].second << "类型的书有" << s[i].first << "本" <<endl;
}
}
/***************
函数名: ShowAll()
输入: 无
功能: 显示菜单
输出: 无
***************/
void ShowAll()
{
cout <<" *--------------------------图书管理系统--------------------------*"<< endl;
cout <<" | 1 查找 |"<< endl;
cout <<" | 2 插入 |"<< endl;
cout <<" | 3 删除 |"<< endl;
cout <<" | 4 修改 |"<< endl;
cout <<" | 5 排序 |"<< endl;
cout <<" | 6 计数 |"<< endl;
cout <<" | 7 退出 |"<< endl;
}
/***************
函数名: MoDify(string x)
输入: string x
功能: 修改信息
输出: 无
***************/
void LinkList:: MoDify(string x)
{
LNode*p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr)
{
if (p->data.name == x|| p->data.no == x)//查找成功,结束函数并返回序号
{
string s1,s2,s3;
cout << " 在系统中的序号是 : " << count << endl;
cout << " 书名为:" << p->data.name << endl;
cout << " 价格是:" << p->data.price << endl;
cout << " 书码为:" << p->data.no << endl;
cout <<" 修改的书名为" <<endl;
cout <<" ";
cin >> s1 ;
p->data.name = s1;
cout <<" 修改的价格为" <<endl;
cout <<" ";
cin >> s2 ;
p->data.price = s2;
cout <<" 修改的书码为" <<endl;
cout <<" ";
cin >> s3 ;
p->data.no = s3;
system("pause");
break;
}
p = p->next;
count++;
}
if(p==nullptr) cout << " 没有这本书" << endl;
}
void Loop()
{
string s1 = "1",s2 = "2",s3 = "3",s4 = "4",s5 = "5",s6 = "6";
string s7 = "7",s8;
LinkList book;
while(1)
{
ShowAll();
cout << " 请输入1~7任意数字可进入对应的功能,其他数字或者符号为无效命令" << endl;
if(book.Empety()) cout << " 温馨提示 :目前系统中没有一本书建议先插入一些书" <<endl;
cout <<" 你选择的功能是 : " <<endl;
cout <<" ";
cin >> s8;
if(s8 == s1)
{
cout << " 请输入书的关键信息" << endl;
string ss;
cout <<" ";
cin >> ss;
book.Locate( ss );
cout <<" ";
system("pause");
}
else if(s8 == s2)
{
book.Insert();
cout <<" ";
system("pause");
}
else if(s8 == s3)
{
cout << " 你想要删除第几本书?请输入一个数字" << endl;
cout <<" ";
int n;
cin >> n;
book.Delete(n);
cout <<" ";
system("pause");
}
else if(s8 == s4)
{
cout << " 请输入需要修改的书的关键信息" << endl;
string ss;
cout <<" ";
cin >> ss;
book.MoDify( ss );
cout <<" ";
system("pause");
}
else if(s8 == s5)
{
book.Sort();
system("pause");
}
else if(s8 == s6)
{
cout << " 数量为" << book.Length() <<endl;
cout <<" ";
system("pause");
}
else if(s8 == s7)
{
cout << " 确定退出吗? <yes or no >" << endl;
string ss;
cout <<" ";
cin >> ss;
if(ss != "yes") continue;
else
{
cout << " 正在退出" << endl;
Sleep(4000);
cout << " 退出成功" << endl;
break;
}
}
else
{
while(s8!=s1&&s8!=s2&&s8!=s3&&s8!=s4&&s8!=s5&&s8!=s6&&s8!=s7)
{
cout <<" 你输入的是无效指令,请重新输入" << endl;
cout <<" ";
cin >> s8;
}
}
system("cls");
}
}
int main()
{
Loop();
return 0;
}