基于链表的图书信息管理

问题分析:

出版社有一些图书数据为简单起见在此假设每种图书只包括三部分信息:ISBN 书名和价格文件中的部分数据如图所示。现要求实现一个图书信息管理系统包括以下6个具体功能。

查找根据指定的ISBN或书名查找相应图书的有关信息并返回该图书在表中的位置序号。

插入插入一种新的图书信息。

删除删除一种图书信息。

修改根据指定的ISBN,修改该图书的价格。

排序将图书按照价格由低到高进行排序。

计数统计图书表中的图书数量。

算法步骤:

创建链表构建添加图书查找图书删除图书修改图书按价格排序按序号排序统计数目以及清空图书的函数。用死循环进行交互在合适的地方退出最后结束程序时调用析构函数释放内存空间。

算法描述:

创建链表实例。

添加图书:获取用户输入,创建新图书节点,插入链表头部。

查找图书:输入ISBN,遍历链表查找并输出信息。

删除图书:输入ISBN,遍历链表找到并删除对应节点。

修改图书:输入ISBN,找到节点并允许用户修改信息。

按价格排序:调用排序方法,更新链表顺序。

显示图书列表:遍历链表,输出所有图书信息。

退出程序:提供退出选项,结束程序。

循环操作:循环执行以上步骤,直到用户选择退出。

清理内存:程序结束时释放链表内存防止内存泄漏。

工具环境:

Dev-c++   TDM-GCC 4.9.2 64-bit   debug   ISO C++11

代码:

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

class Book {
public:
    int num;           //图书的序号
    string ISBN;       //图书的ISBN编号
    string name;       //图书的名称
    int price;         //图书的价格
    Book(int num, const string& ISBN, const string& name, int price)
        : num(num), ISBN(ISBN), name(name), price(price) { } 
};

class LinkList {
public:
    struct Node {
        class Book* book;     //指向图书信息的指针
        struct Node* next;    //指向下一个节点的指针
        Node(Book* book) : book(book), next(NULL) { }
    }; 

    LinkList( ) : head(NULL), count(0) { }
    ~LinkList( ) {  clear( );  }
	
	void refresh ( ) {
	    system ("pause");               //暂停程序,等待用户输入
	    system ("cls");                 //清屏
	}
	
	void showmenu ( ) {
		cout << "请选择操作:" << endl;
        cout << "********1. 查找图书********" << endl;
        cout << "********2. 添加图书********" << endl;
        cout << "********3. 删除图书********" << endl;
        cout << "********4. 修改图书********" << endl;
        cout << "********5. 按价格排序******" << endl;
        cout << "********6. 按序号排序******" << endl; 
        cout << "********7. 清空图书********" << endl;
        cout << "********8. 统计书数********" << endl;
        cout << "********0. 退出************" << endl;
	}
	
    void clear( ) {                     //清除所有图书 
        Node* current = head;           //从头节点开始
        while (current != NULL) {
            Node* temp = current;       //临时保存当前节点
            current = current->next;    //移动到下一个节点
            delete temp->book;          //删除图书信息
            delete temp;                //删除节点(从头开始删) 
        }
        head = NULL;                    //将头节点设置为NULL
        count = 0;                      //节点数量设置为0
    }

    void insert(const Book& book) {                   //前插操作,添加书 
        Node* newNode = new Node(new Book(book));     //创建一个新的节点,匿名对象,拷贝构造 
        newNode->next = head;                         //将新节点指向原来的头节点
        head = newNode;                               //将头节点更新为新节点
        count++;                                      //节点数量加1
    }

    void remove(const string& ISBN) {                 //删除书 
        Node* prev = NULL;                            //前一个节点
        Node* current = head;                         //当前节点
        while (current != NULL && current->book->ISBN != ISBN) {
            prev = current;                           //更新前一个节点
            current = current->next;                  //移动到下一个节点
        }
        if (current != NULL) {                        //如果找到了对应的节点
        	deleteNode(prev);                         //那就删掉这个结点嘿嘿!
			cout << "删除成功" << endl; 
        } else {
        	cout << "没有找到哎" << endl; 
		}
    }

    void alter(const string& ISBN) {                     //修改书 
        Node* node = findBookByISBN(ISBN);               //找ISBN对应的节点
        if (node != NULL) {                              //如果找到了对应的节点
            cout << "请输入修改后的图书信息:" << endl;
            cout << "ISBN(不变): " << ISBN << endl;
            cout << "书名:"; cin >> node->book->name;   //输入新的书名
            cout << "价格:"; cin >> node->book->price;  //输入新的价格
        } else {
            cout << "找不到该ISBN的图书。" << endl;
        }
        cin.ignore( );                                   //忽略输入流中的换行符***** 
    }

    void order( ) {                                      //按价格排序 
        if (head == NULL || head->next == NULL) return;  //如果链表为空或只有一个节点,不需要排序
        bool swapped;                                    //标记是否发生了交换
        Node* current = head;                            //当前节点
        do {
            swapped = false;                             //初始化为未发生交换
            current = head;                              //从头节点开始
            while (current->next != NULL) {              //遍历链表
                if (current->book->price > 
					current->next->book->price) {        //如果当前节点的价格大于下一个节点的价格
                    swap(current, current->next);        //交换两个节点的内容
                    swapped = true;                      //标记发生了交换(只动值,不动指针哦)*-* 
                }
                current = current->next;                 //移动到下一个节点
            }
        } while (swapped);                               //如果发生了交换,继续下一轮排序
    }

    void display( ) const {                              //嘿嘿,展示一下 
    	if (count == 0) {
    		cout << "看什么看,一本书都没有" << endl;
			return; 
		}
        cout << setw(6) << "序号" 
			 << setw(18) << "ISBN"
			 << setw(25) << "书名"
			 << setw(8) << "价格" << endl;
        Node* current = head;                            //从头节点开始
        while (current != NULL) {                        //遍历链表
            cout << setw(6) << current->book->num  
				 << setw(18) << current->book->ISBN 
				 << setw(25) << current->book->name 
				 << setw(8) << current->book->price << endl;
            current = current->next;                     //移动到下一个节点
        }
    }

    void defaultOrder( ) {                               //按序号排序 
        if (head == NULL || head->next == NULL) return;  //如果链表为空或只有一个节点,不需要排序
        bool swapped;                                    //标记是否发生了交换
        Node* current = head;                            //当前节点
        do {
            swapped = false;                             //初始化为未发生交换
            current = head;                              //从头节点开始
            while (current->next != NULL) {              //遍历链表
                if (current->book->num > 
					current->next->book->num) {          //如果当前节点的序号大于下一个节点的序号
                    swap(current, current->next);        //交换两个节点的内容
                    swapped = true;                      //标记发生了交换
                }
                current = current->next;                 //移动到下一个节点
            }
        } while (swapped);                               //如果发生了交换,继续下一轮排序
    }

    int getCount( ) const {                              //获取当前节点数量 
        return count;  
    }

    Node* findBookByISBN(const string& ISBN) const {     //按ISBN值查找 
        Node* current = head;                            //从头节点开始
        while (current != NULL) {                        //遍历链表
            if (current->book->ISBN == ISBN) {           //如果找到了对应的ISBN
                return current;                          //返回节点指针
            }
            current = current->next;                     //移动到下一个节点
        }
        return NULL;                                     //如果没有找到,返回NULL
    }
private:
    Node* head;                                          //链表的头节点
    int count;                                           //链表中的节点数量

    void deleteNode(Node* prev) {                        //删除节点 
        Node* toDelete = prev ? prev->next : head;       //要删除的节点,很有东西的好不好 @…^…@ 
        if (toDelete == head) {                          //如果是头节点
            head = head->next;                           //更新头节点
        } else {
            prev->next = toDelete->next;                 //更新前一个节点的指向
        }
        delete toDelete->book;                           //删除图书信息
        delete toDelete;                                 //删除节点
        count--;                                         //节点数量减1
    }

    void swap(Node* a, Node* b) {                        //换值不换结点哦! 
        Book temp = *a->book;                            //临时保存节点a的内容
        *a->book = *b->book;
        *b->book = temp;                                 //交换节点a和b的内容
    }
};

int main( ) {
    LinkList bookList;                                   //创建一个链表对象
    Book books[ ] = {                                    //定义一个图书数组,包含一些初始图书信息
        {1,"9787302257646","程序设计基础",25},
        {2,"9787302219972","单片机技术及应用",32},
		{3,"9787302203513","编译原理",46},
		{4,"9787811234923","汇编语言程序设计教程",21},
		{5,"9787512100831","计算机操作系统",17},
		{6,"9787302265436","计算机导论实验指导",18},
		{7,"9787302180630","实用数据结构",29},
		{9,"9787302171676","C#面向对象程序设计",39},
		{10,"9787302250692","C语言程序设计",42},
		{11,"9787302150664","数据库原理",35},
		{12,"9787302260806","Java编程与实践",56},
		{13,"9787302252887","Java程序设计与应用教程",39},
		{14,"9787302198505","嵌入式操作系统及编程",25},
		{15,"9787302169666","软件测试",24},
		{16,"9787811231557","Eclipse基础与应用",35},
    };
	for (int i = 0; i < sizeof(books) / sizeof(books[0]); i++) {
	    bookList.insert(books[i]);                       //将初始图书信息添加到链表中
	}
    string choice;                                          //用户选择的操作
    while (true) {                                          //无限循环,直到用户选择退出
		bookList.display( );
		bookList.showmenu ( );
        cin >> choice;                                      //输入操作选项
        switch (choice[0]) {                                //根据用户选择的操作执行相应的功能
            case '1': 
	            { 
	                string ISBN;
	                cout << "请输入要查找的图书ISBN:"; cin >> ISBN;
	                LinkList::Node* node = bookList.findBookByISBN(ISBN);  //查找图书
	                if (node != NULL) {                                    //如果找到了图书
	                    cout << "找到图书:" << endl;
	                    cout << "ISBN: " << node->book->ISBN << endl;
	                    cout << "书名: " << node->book->name << endl;
	                    cout << "价格: " << node->book->price << endl;
	                } else {
	                    cout << "找不到该ISBN的图书。" << endl;
	                }
	                bookList.refresh ();                                   //清屏并暂停
	                break;
	            }
            case '2': 
	            {
	                int num,price; 
	                string ISBN, name;
	                cout << "请输入要添加的图书信息:" << endl;
	                cout << "序号:"; cin >> num;
	                cout << "ISBN:"; cin >> ISBN;
	                cout << "书名:"; cin >> name;
	                cout << "价格:"; cin >> price;
	                bookList.insert(Book(num, ISBN, name, price));      //添加图书,匿名对象,有参构造 
	                bookList.refresh ( );                               //清屏并暂停
	                break;
	            }
            case '3': 
	            {
	                string ISBN;
	                cout << "请输入要删除的图书ISBN:"; cin >> ISBN;
	                bookList.remove(ISBN);                              //删除图书
	                bookList.refresh ( );                               //清屏并暂停
	                break;
	            }
            case '4': 
	            {
	                string ISBN;
	                cout << "请输入要修改的图书ISBN:"; cin >> ISBN;
	                bookList.alter(ISBN);                               //修改图书
	                bookList.refresh ( );                               //清屏并暂停
	                break;
	            }
            case '5':
                bookList.order( );                                      //按价格排序
                bookList.display( );                                    //显示图书列表
                bookList.refresh ( );                                   //清屏并暂停
                break;
            case '6':
                bookList.defaultOrder( );                               //按序号排序
                bookList.display( );                                    //显示图书列表
                bookList.refresh ( );                                   //清屏并暂停
                break;
            case '7':
            	{
            		while (true) {
            			cout << "你确定吗" << endl
						     << "1. 确定" << endl
						     << "2. 取消" << endl;
						string choice;
						cin >> choice;
						if (choice == "1") {
							cout << "毁灭吧" << endl;
							bookList.clear( );
							bookList.refresh ( );
							break;
						} else if (choice == "2") {
							cout << "清空操作已取消" << endl;
							bookList.refresh ( );
							break;
						} else {
							cout << "孩子,你在搞笑吗?请重新输入" << endl; 
						}
					}
					break;
				} 
            case '8':
            	{
            		int num = bookList.getCount( );
	            	cout << "现在有" << num << "本书" << endl;
	            	bookList.refresh ( );
	            	break;
				}
            case '0':
                cout << "欢迎下次光临" << endl;
                return 0;                             //退出程序
            default:
                cout << "无效的选项,请重新选择。" << endl;
                bookList.refresh ( );                 //清屏并暂停
                break;
        }
    }
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值