用单链表实现图书信息的管理C++

这是图书信息测试txt文件,由于是oj搞过来的代码,只是简单复制粘贴了一下oj里面的代码段,然后我又自己加了一些逻辑是之成为一个完整的图书管理系统。录入信息的方式一共有3种,具体怎么录入信息看提示。

可能部分逻辑并不是很完美,只是实现了基本的功能,之后有时间还会优化一下逻辑结构

8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define OK 1
using namespace std;

typedef struct//定义图书结构体
{
    string IBNS;
    string NAME;
    float PRICE;
}Book;

typedef struct LNode
{
    int length;
    Book data;
    struct LNode* next;

}LNode, * LinkList;

int Init(LinkList& L);//初始化链表
int Tail_Insert(LinkList& L);//尾插法储存图书信息,结束条件是0,0,0
int Tail_Insert_n(LinkList& L);//尾插,先输入图书数目再存入
int Head_Insert(LinkList& L);//头插法,逆序存储
int Traverse(LinkList& L);//遍历图书,求表长
int Print(LinkList L);//打印所有图书
int Sort(LinkList& L);//按照价格从大到小排序,并输出平均价格
int Modify(LinkList& L);//修改图书价格信息函数
void Find(LinkList& L);
int Find_expensivest(LinkList L);//查找最贵图书
int Find_byname(LinkList L);//根据书名查找图书详细信息
int Find_n(LinkList L);//查找第n本图书的信息
int Insert_Pos(LinkList& L);//插入新图书信息
int Delete(LinkList& L);//删除第n本图书的信息
int Delete_re(LinkList L);//IBNS号重复的图书的信息
int Insert(LinkList L);

void Clear();//清屏
void Index(LinkList L);
void Instruct(LinkList L);//指令集合函数
void Print_sum(LinkList L);
void Index(LinkList L)
{
    int Chioce=12;
    int flag = 1;
    while (flag) {
        cout << "\n***************************************Welcome to the Books Management System (BMS)*************************************\n";
        cout << "1.查询图书数量\n2.输出所有图书信息\n3.在指定位置插入图书\n4.根据位置删除图书信息\n5.根据输入信息的查找\n6.查看图书的总数\n7.修改价格信息并将生成的信息导入新文件\n8.排序并将排序后的信息导入新的文件\n9、查重(对于IBSN号相同的图书只保留一本\n10、退出" << endl;
        cout << "请选择" << endl;
        cin >> Chioce;
        Clear();
        switch (Chioce) {
        case 1:Traverse(L); flag = 0; break;
        case 2:Print(L); flag = 0; break;//输出所有图书信息
        case 3:Insert_Pos(L); flag = 0; break;//插入图书信息
        case 4:Delete(L); flag = 0; break;//删除图书信息
        case 5:Find(L); flag = 0; break;//根据书名查找图书
        case 6:Print_sum(L); flag = 0; break;
        case 7:Modify(L); flag = 0; break;//修改图书价格
        case 8:Sort(L); flag = 0; break;//冒泡排序
        case 9:Delete_re(L); flag = 0; break;
        case 10:cout << "\t成功退出,谢谢使用!"; exit(0);
        default:
            printf("输错啦! 请输入1 ~ 9之间的整数\n");
            break;
        }
    }
}

int main()
{
    LinkList L;
    Init(L);//初始化链表
    Insert(L);//尾插法储存图书信息,结束条件是0,0,0
    Traverse(L);
    Index(L);
    Instruct(L);
    return 0;
}

void Instruct(LinkList L)
{
    int Choice=3;
    while (1)
    {
        cout << "请选择:\n1.查看指令\n2.退出程序\n请输入..." << endl;
        cin >> Choice;
        Clear();
        switch (Choice)
        {
        case 1:Index(L); break;
        case 2:cout << "退出成功!再见~~" << endl; exit(0); break;
        default:
            printf("输错啦!请看清楚,再重新输入1或2哦\n请输入...\n");
        }
    }
}

void Find(LinkList& L)
{
    int n;
    printf("请查询方式选择:\n1、最贵的图书\n2、某一本图书的详细信息\n3、按位置查找图书的详细信息\n4、返回主菜单\n");
    int flag = 1;
    while (flag)
    {
        cin >> n;
        switch (n)
        {
        case 1:Find_expensivest(L); flag = 0; break;
        case 2:Find_byname(L); flag = 0; break;
        case 3:Find_n(L); flag = 0; break;
        case 4:continue;
        default:
            printf("输错啦!请看清楚,再重新输入1或2哦\n请输入...\n");
        }
    }     
}

void Clear()
{
    cin.clear();
    cin.ignore(1, EOF);
    cout << endl;
    system("cls");//清屏函数
}


int Init(LinkList& L)//初始化链表
{
    L = new LNode;
    L->next = NULL;
    return OK;
}

int Insert(LinkList L)
{
    int choice = 0;
    printf("请你先按要求录入图书信息哈:\n请选择:\n1、以输入0 0 0作为结束标志\n2、先输入想要录入图书信息的数量,再依次输入图书\n");
    printf("3、先输入图书数量再依次输入图书信息(逆序存储)\n注意:输入图书信息的格式:IBNS NAME PRICE 之间用空格隔开,两个数据之间用换行分开\n");
    cin >> choice;
    switch (choice)
    {
    case 1:Tail_Insert(L); break;
    case 2:Tail_Insert_n(L); break;
    case 3:Head_Insert(L); break;
    default:
        printf("输错啦,啊啊啊啊啊,请你看清楚再选,再次输入\n请输入...\n");
    }
    Clear();
    cout << "录入成功,请选择操作" << endl;
    return OK;
}

void Print_sum(LinkList L)
{
    cout << "我们一共搜寻到了" << L->length << "本图书" << endl;
}
int Tail_Insert(LinkList& L)//尾插法,建立的是与输入顺序相同的链表
{
    Clear();
    LinkList p = L;//p存储链表L的头指针,指向头结点
    string IBNS;
    string NAME;
    float PRICE;
    cout << "请直接输入图书信息并以 0 0 0结束" << endl;
    while (cin >> IBNS >> NAME >> PRICE)
    {
        if (IBNS == "0" && NAME == "0" && PRICE == 0)
            break;//oj中的停止输入条件
        else//创建新结点
        {
            LinkList q = new LNode;
            q->data.IBNS = IBNS;//为新结点数据域赋值
            q->data.NAME = NAME;
            q->data.PRICE = PRICE;
            q->next = NULL;//指针q的下一个结点设置为空
            p->next = q;//将指针q链接在p的后面
            p = q;//将q赋值给p,相当于结点p后移
        }
    }
    return OK;
}

int Tail_Insert_n(LinkList& L)//尾插法
{
    Clear();
    LinkList p = L;//p存储链表L的头指针,指向头结点
    string IBNS;
    string NAME;
    float PRICE;
    int n=0;
    cout << "请输入您想要录入图书的数量" << endl;
    cin >> n;
    cout << "好了可以开始录入图书信息啦" << endl;
    while (n--)
    {
        LinkList q = new LNode;
        cin >> IBNS >> NAME >> PRICE;
        q->data.IBNS = IBNS;
        q->data.NAME = NAME;
        q->data.PRICE = PRICE;
        q->next = NULL;
        p->next = q;
        p = q;//p指向q
    }
    return OK;
}

int Head_Insert(LinkList& L)//头插法,逆序存储
{
    Clear();
    int n;
    cout << "请输入您想要录入图书的数量" << endl;
    cin >> n;
    cout << "好了可以开始录入图书信息啦" << endl;
    while (n--)
    {
        LinkList p = new LNode;
        cin >> p->data.IBNS >> p->data.NAME >> p->data.PRICE;
        p->next = L->next;
        L->next = p;
    }
    return OK;
}


int Traverse(LinkList& L)
{
    LinkList p = L; //p储存头指针,指向头结点
    L->length = 0;//将表长初始化为0
    while (p->next)
    {
        L->length++;
        p = p->next;
    }
    return OK;
}

int Insert_Pos(LinkList& L)
{
    LinkList q = new LNode;//创建要插入的结点
    LinkList p = L;//定义指针指向头结点
    int n = 1;
    cout << "请输入你想要插入图书的具体位置哈." << endl;
    cin >> n;//输入结点插入的位置
    cout << "好了你可以输入你想要插入图书的信息了,分别为:IBNS号,NAME,PRICE,以空格隔开,回车结束" << endl;
    cin >> q->data.IBNS >> q->data.NAME >> q->data.PRICE;//输入插入结点的数据信息
    n--;
    if (n<1 || n>L->length)
        cout << "你这想插入的位置不对哈" << endl;
    else
    {
        while (n--)
            p = p->next;//寻找插入结点位置
        q->next = p->next; p->next = q;//改变指针指向插入结点
        cout << "插入成功了下面是现有的图书信息" << endl;
        Print(L);
    }
    return OK;
}

int Delete(LinkList& L)
{
    int n=0;
    LinkList p = L;
    LinkList q;
    cout << "请输入要删除图书的位置" << endl;
    cin >> n;//输入将要删除数据的位置
    int i = 0;
    while ((p->next) && (i < n - 1))//查找第n-1个节点,p指向该结点
    {
        p = p->next;
        ++i;
    }
    if (!(p->next) || (i > n - 1))
        cout << "Sorry,the position to be deleted is invalid!" << endl;
    else
    {
        q = p->next;//临时保存删除结点的地址
        p->next = q->next;//改变删除结点前驱节点的指针指向
        delete q;
        cout << "这是删除之后的所有图书信息" << endl;
        Print(L);
    }
    return OK;
}

int Delete_re(LinkList L)
{
    LinkList p = L->next;//定义指针指向首元结点
    while (p)
    {
        LinkList q = p;
        while (q->next)
        {
            //我们已经用第一层循环得到了要比较的结点q得到了,再来一个循环将链表中的元素与q挨个比较
            if (p->data.IBNS == q->next->data.IBNS)
            {
                LinkList re;
                re = q->next;//临时保存删除结点的地址
                q->next = q->next->next;//改变删除结点前驱节点的指针指向
                delete re;//释放结点空间
            }
            else
                q = q->next;
        }
        p = p->next;
    }
    Traverse(L);//遍历链表求表长
    cout << L->length << endl;//根据题目要求输出去重后的链表长度
    Print(L);//打印
    return OK;
}


int Print(LinkList L)
{
    LinkList p = L;//用指针p指向头结点
    p = L->next;//让指针指向链表首元结点开始打印
    while (p->next)
    {
        cout << p->data.IBNS << " " << p->data.NAME << " " << fixed << setprecision(2) << p->data.PRICE << endl;
        p = p->next;
    }
    cout << p->data.IBNS << " " << p->data.NAME << " " << fixed << setprecision(2) << p->data.PRICE << endl;
    return OK;
}

int Sort(LinkList& L)
{
    for (int i = 0; i < L->length - 1; i++)
    {
        LinkList p = L->next;//指针掉头,再次指向首元结点,再开始排序
        Book t;//定义结构体来做交换
        for (int j = 0; j < L->length - i - 1; j++)//冒泡排序
        {
            if (p->data.PRICE < p->next->data.PRICE)
            {
                t = p->data;
                p->data = p->next->data;
                p->next->data = t;
            }
            p = p->next;
        }
    }
    cout << "这是排序之后的图书信息" << endl;
    Print(L);
    return OK;
}

int Modify(LinkList& L)
{
    LinkList p = L->next;//指向首元结点
    float Sum = 0, Ave = 0;//定义并初始化总价格、平均价格
    while (p)
    {
        Sum += p->data.PRICE;
        p = p->next;
    }
    Ave = Sum / L->length;
    cout << fixed << setprecision(2) << Ave << endl;//输出平均价格
    p = L->next;//p指向链表的首元结点
    while (p)
    {
        if (p->data.PRICE < Ave)
            p->data.PRICE = p->data.PRICE * 1.2;
        else
            p->data.PRICE = p->data.PRICE * 1.1;
        p = p->next;
    }
    cout << "下面是修改价格之后的图书信息" << endl;
    Print(L);
    return OK;
}

int Find_expensivest(LinkList L)
{
    LinkList p = L->next;//定义头指针指向首元结点
    int count = 0;
    float max = L->data.PRICE;//将链表首元结点的价格赋给max
    while (p->next)
    {
        if (max < p->next->data.PRICE)
            max = p->next->data.PRICE;
        p = p->next;
    }
    p = L->next;//指针p指向首元结点
    while (p)
    {
        if (p->data.PRICE == max)
            count++;
        p = p->next;
    }
    cout <<"查找到最贵的图书有"<< count <<"本"<< endl;
    p = L->next;
    cout << "下面是最贵图书的信息" << endl;
    while (p)
    {
        if (p->data.PRICE == max)
        {
            cout << p->data.IBNS << " " << p->data.NAME << " " << fixed << setprecision(2) << p->data.PRICE << endl;
        }
        p = p->next;
    }
    return OK;
}

int Find_byname(LinkList L)//根据书名查找图书详细信息
{
    int n;
    cout << "请你输入想要查找的次数" << endl;
    cin >> n;
    LinkList p = L->next;//指针p指向首元结点
    int flag = 0;
    int k = 0;
    while (n--)//多次查找
    {
        string name;
        int i = 0;
        cout << "请输入图书名字" << endl;
        cin >> name;
        k++;
        while (p)
        {
            if (name.compare(p->data.NAME) == 0)//寻找相同的name并标记、计数,主要是根据oj的需要进行输出
            {
                if (n == 0)
                    flag = 1;
                i++;
            }
            p = p->next;//指针指向下一个结点
        }
        if (flag)
        {
            cout << "名为" << name << "的图书总的有" << i << "本" << endl;
            p = L->next;//重新将p指向首元结点再遍历
            while (p)
            {
                cout << "这是您要查找图书的所有信息" << endl;
                if (name == p->data.NAME)
                {
                    
                    cout << p->data.IBNS << " " << p->data.NAME << " " << fixed << setprecision(2) << p->data.PRICE << endl;
                }
                p = p->next;
            }
        }
        else
        {
            cout << "抱歉,没有找到您想要的图书" << endl;
        }
        p = L->next;
    }
    return OK;
}

int Find_n(LinkList L)//查找第n本图书的信息
{
    int n;
    cout << "请输入您想要查找图书次数" << endl;
    cin >> n;
    LinkList p = L->next;//指针p指向首元结点
    int flag = 0;
    while (n--)//重复查找n次
    {
        int m;//要查找的位置
        cout << "请输入要查找的位置" << endl;
        cin >> m;
        if (m < 1)//查找的位置要合理
            cout << "抱歉,你输错了哈。" << endl;
        else if (m > L->length)
            cout << "抱歉,我们没有这么多图书哈。" << endl;

        else
        {
            for (int i = 0; i < m - 1; i++)
                p = p->next;
            cout << "这是您想要查找图书的详细信息" << endl;
            cout << p->data.IBNS << " " << p->data.NAME << " " << fixed << setprecision(2) << p->data.PRICE << endl;
        }
        p = L->next;
    }
    return OK;
}

你可能感兴趣的:(管理系统,c++,开发语言,后端)