链表图书信息管理系统
时间: 2024-12-28 16:23:16 浏览: 10
### 使用链表实现图书信息管理系统
#### 链表简介
链表是一种线性数据结构,其中每个节点包含两部分:一部分用于存储数据元素;另一部分是一个指向下一个节点的指针。这种特性使得链表非常适合动态增删操作频繁的应用场景[^1]。
对于图书信息管理系统而言,采用链表可以方便地进行书籍记录的插入、删除以及遍历等操作而无需移动其他元素的位置,提高了效率并简化了程序逻辑设计。
#### 功能需求分析
基于上述描述,在构建该系统时应考虑以下几个方面:
- **增加图书信息**
- **查询图书信息**
- **删除图书信息**
- **修改图书信息**
- **打印所有图书列表**
- **按照特定条件排序(如按书名字母顺序排列)**
#### 数据结构定义
为了更好地管理和维护每本书的信息,这里先定义一个`BookNode`类来表示单个书籍条目,并通过这些节点组成一条完整的双向循环链表以支持高效的前后向迭代访问。
```cpp
#include <iostream>
#include <string>
using namespace std;
// 定义图书结点
struct BookNode {
string title; // 书名
string author; // 作者
int yearPublished; // 出版年份
BookNode* next;
// 构造函数初始化成员变量
BookNode(string t, string a, int y):title(t),author(a),yearPublished(y),next(nullptr){}
};
```
#### 主要功能模块实现
##### 增加新书
当用户想要录入一本新的书籍资料时,则需创建一个新的`BookNode`实例并将它连接到当前已存在的链表末端。
```cpp
void addNewBook(BookNode*& headRef, const string& bookTitle, const string& bookAuthor, int pubYear){
// 创建新节点对象
BookNode *newEntry = new BookNode(bookTitle,bookAuthor,pubYear);
if (!headRef){ // 如果是第一个节点
headRef=newEntry;
newEntry->next=headRef;
}else{
// 找到最后一个节点
BookNode *current = headRef;
while (current->next != headRef) current=current->next;
// 插入新节点作为最后一个节点
current->next=newEntry;
newEntry->next=headRef;
}
}
```
##### 查询指定书籍详情
提供两种方式查找目标书籍——根据书名精确匹配或是模糊搜索含有关键词的作品名称。
```cpp
bool findBookByTitle(const BookNode* headPtr,const string& targetTitle,string &resultInfo){
bool found=false;
resultInfo="";
if(headPtr!=nullptr){
do{
if(headPtr->title==targetTitle){
ostringstream oss;
oss << "找到《"<<headPtr->title<<"》\n"
<<"作者:"<<headPtr->author<<"\n出版时间:"<<headPtr->yearPublished<<endl;
resultInfo=oss.str();
found=true;
break;
}
headPtr=headPtr->next;
}while(headPtr!=nullptr && !found);
if(!found)
resultInfo+="未查找到符合条件的数据。\n";
}
return found;
}
vector<string> searchBooksContainKeyword(const BookNode* headPtr,const string& keyword){
vector<string> matchedTitles;
if(headPtr!=nullptr){
do{
if(headPtr->title.find(keyword)!=std::string::npos ||
headPtr->author.find(keyword)!=std::string::npos )
matchedTitles.push_back(headPtr->title+" ("+to_string(headPtr->yearPublished)+")");
headPtr=headPtr->next;
}while(headPtr!=nullptr );
}
return matchedTitles;
}
```
##### 删除某本具体作品
允许管理员依据唯一标识符(此处假设为书名)移除对应项。
```cpp
bool removeBookWithTitle(BookNode *&headRef, const string &delTitle) {
if (!headRef || delTitle.empty()) return false;
BookNode *prev = nullptr,*curr = headRef;
do {
prev = curr;
curr = curr -> next;
if(curr->title == delTitle){
if(prev == curr){//只有一个节点的情况
delete curr;
headRef=nullptr;
} else{//多个节点情况下的处理
prev->next = curr->next;
if(curr == headRef)//如果被删除的是头节点
headRef = prev;
delete curr;
}
return true;
}
} while (curr != headRef);
return false;
}
```
##### 修改现有记录中的字段值
针对已经存在于数据库里的项目更新其属性信息。
```cpp
bool updateExistingRecord(BookNode *headRef, const string &updateTarget,
const string &newValueForField,int fieldIndex/*0-title,1-author,2-year*/) {
if(fieldIndex<0||fieldIndex>2)return false;//非法索引范围外抛异常
auto it = headRef;
do {
if(it->title==updateTarget){
switch(fieldIndex){
case 0:it->title=newValueForField;break;
case 1:it->author=newValueForField;break;
case 2:{
try{
it->yearPublished=stoi(newValueForField);
}catch(...){
cerr<<"输入不是有效的整数!"<<endl;
return false;
}
};break;
}
return true;
}
it=it->next;
} while(it!=headRef);
return false;
}
```
##### 输出全部藏书清单
最后还应该具备一次性展示整个馆藏的能力。
```cpp
void displayAllRecords(const BookNode *headPtr){
cout<<"\t【图书馆藏】\n\n";
if(headPtr!=nullptr){
do{
printf(" %-30s | %s (%d)\n",headPtr->title.c_str(),headPtr->author.c_str(),
headPtr->yearPublished);
headPtr=headPtr->next;
}while(headPtr!=nullptr);
}else{
puts("\n暂无任何收藏...\n");
}
}
```
以上即是对如何利用C++语言配合链表这一基础抽象类型搭建起简易版本的图书信息系统进行了较为详细的阐述与编码示范。
阅读全文