一、实验目的:
使用单链表实现案例2.3的图书管理系统,要求实现查找、插入、删除和计数功能。要求包含主函数,用c语言或者c++实现。
二、实验仪器或设备:
操作系统:Windows11
编程环境:Dev-cpp 5.11
三、算法总体设计
1.创建节点
2.头插法
3.查找
4. 打印链表
5.从文件读取书籍信息到链表
6. 计数
7.用户交互
四、实验步骤(包括主要步骤、命令分析等)
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #include <iomanip> 5 #include <limits> 6 #include <vector> 7 using namespace std; 8 typedef int Status; 9 const Status ERROR = -1; 10 const Status OVERFLOW = -2; 11 const Status OK = 1; 12 // 图书的信息结构体 13 struct Book { 14 string id; // ISBN 15 string name; // 书名 16 double price; // 定价 17 }; 18 // 单链表节点结构体 19 struct Node { 20 Book data; 21 Node* next; 22 }; 23 // 创建新节点 24 Node* createNode(const Book& book) { 25 Node* newNode = new Node(); 26 newNode->data = book; 27 newNode->next = NULL; 28 return newNode; 29 } 30 // 插入节点到链表头部 31 void insertNodeByHead(Node*& head, const Book& book) { 32 Node* newNode = createNode(book); 33 newNode->next = head; 34 head = newNode; 35 } 36 void deleteNodeByName(Node*& head, const string& bookname) { 37 if (head == NULL) { 38 cout << "链表为空,无法删除节点。" << endl; 39 return; 40 } 41 Node* posLeftNode = NULL; // 用于存储当前节点的前一个节点 42 Node* posNode = head; // 当前节点 43 // 检查头节点是否是目标节点 44 if (posNode->data.name == bookname) { 45 Node* temp = posNode; 46 head = posNode->next; // 更新头指针 47 delete temp; // 删除头节点 48 cout << "删除成功: " << bookname << endl; 49 return; 50 } 51 // 遍历链表查找目标节点 52 while (posNode != NULL && posNode->data.name != bookname) { 53 posLeftNode = posNode; 54 posNode = posNode->next; 55 } 56 if (posNode == NULL) { 57 cout << "未找到书籍: " << bookname << endl; 58 } else { 59 posLeftNode->next = posNode->next; // 从链表中移除目标节点 60 delete posNode; // 释放目标节点的内存 61 cout << "删除成功: " << bookname << endl; 62 } 63 } 64 // 根据书名进行查找 65 void findNodeByName(Node*& head, const string& bookname) { 66 Node* posLeftNode = head; 67 Node* posNode = head->next; 68 if(posLeftNode->data.name == bookname) 69 { 70 cout << "成功找到书籍: " << bookname << endl; 71 cout << "书籍的信息为: " << setw(10) <<posLeftNode->data.id << setw(30) <<posLeftNode->data.name << setw(15) << posLeftNode->data.price << endl; 72 } 73 else{ 74 while (posNode != NULL && posNode->data.name != bookname) { 75 posLeftNode = posNode; 76 posNode = posNode->next; 77 } 78 if (posNode == NULL) { 79 cout << "未找到书籍: " << bookname << endl; 80 return; 81 } else { 82 cout << "成功找到书籍: " << bookname << endl; 83 cout << "书籍的信息为: " << setw(10) <<posNode->data.id << setw(30) << posNode->data.name << setw(15) << posNode->data.price << endl; 84 } 85 } 86 } 87 // 打印链表 88 void printList(Node* head) { 89 if (head == NULL) { 90 std::cout << "链表为空" << std::endl; 91 return; 92 } 93 cout << std::setw(10) << "ID" << std::setw(30) << "书名" << std::setw(15) << "价格" << std::endl; 94 Node* pMove = head; // 直接从 head 开始遍历,因为没有头节点 95 while (pMove != NULL) { 96 cout <<setw(10) << pMove->data.id <<setw(30) << pMove->data.name<<setw(15) << pMove->data.price <<endl; 97 pMove = pMove->next; 98 } 99 } 100 // 从文件读取书籍信息到链表 101 Status readBooksFromFile(Node*& head, const string& filename) { 102 ifstream infile(filename.c_str()); 103 if (!infile.is_open()) { 104 cerr << "文件打开失败 " << filename << endl; 105 return ERROR; 106 } 107 string id, name; 108 double price; 109 infile.ignore(numeric_limits<streamsize>::max(), '\n'); // 跳过标题行 110 while (infile >> id >> name >> price) { 111 Book book = {id, name, price}; 112 insertNodeByHead(head, book); 113 } 114 infile.close(); 115 return OK; 116 } 117 //计数 118 int countBooks(Node*& head) { 119 int count = 0; 120 Node* posNode = head->next; // 从头节点的下一个节点开始计数 121 while (posNode != NULL) { 122 count++; 123 posNode = posNode->next; 124 } 125 return count; 126 } 127 void clearList(Node*& head) { 128 Node* temp; 129 while (head != NULL) { 130 temp = head; 131 head = head->next; 132 delete temp; 133 } 134 } 135 // 主函数 136 int main() { 137 Node* head = new Node(); // 创建头节点(这里作为哑节点,不存储实际数据) 138 head->next = NULL; 139 string filename = "book.txt"; 140 Status status = readBooksFromFile(head, filename); 141 if (status == OK) { 142 printList(head); 143 } else { 144 cerr << "读取书籍信息失败。" << endl; 145 delete head; // 如果读取失败,释放头节点 146 return 1; 147 } 148 int userkey; 149 string bookname; 150 Book tempBook; 151 while (true) { 152 cout << "\n欢迎来到图书管理系统\n"; 153 cout << "请输入项目前编号执行相关的操作\n"; 154 cout << "[0]退出\n"; 155 cout << "[1]查找\n"; 156 cout << "[2]插入\n"; 157 cout << "[3]删除\n"; 158 cout<< "[4]计数\n"; 159 cout << "请选择: "; 160 cin >> userkey; 161 switch (userkey) { 162 case 0: 163 cout << "退出成功\n"; 164 clearList(head); // 释放整个链表 165 delete head; // 释放头节点 166 return 0; 167 case 1: 168 cout << "【查找】\n"; 169 cout << "请输入要查找的书籍名字: "; 170 cin >> bookname; 171 findNodeByName(head, bookname); 172 173 break; 174 case 2: 175 cout << "【插入】\n"; 176 cout << "请输入ISBN、书名和价格(用空格分隔): "; 177 cin >> tempBook.id >> tempBook.name >> tempBook.price; 178 insertNodeByHead(head, tempBook); 179 printList(head); 180 break; 181 case 3: 182 cout << "【删除】\n"; 183 cout << "请输入要删除的书籍名字: "; 184 cin >> bookname; 185 deleteNodeByName(head, bookname); 186 printList(head); 187 break; 188 case 4: 189 cout<<"【计数】\n"; 190 cout<<"书籍总本数为:"<<countBooks(head); 191 } 192 } 193 return 0; 194 }
1.首页
2.查找功能
3.插入功能
4.删除功能
5.计数功能
6.退出
结语:
通过本次实验,我深入理解了链表的基本操作,包括节点的创建、遍历、访问和删除等。同时,我也学会了如何在链表中根据特定条件查找并删除节点,这对于我掌握数据结构的基本概念和操作方法具有重要意义...