@[TOC]链表实现图书信息管理系统
项目描述
使用C语言的链表实现一个简单的图书信息管理系统,主要功能包括对图书的添加、删除、修改、查询、插入、排序、显示、保存等。
结构体的声明
typedef struct book
{
int number; //图书编号
char name[50]; //图书名
char lendData[50]; //借出日期
char condition[20]; //图书状态
int lendCount; //借阅次数
struct book *next;
}book, *LinkBook;
函数的声明
LinkBook initLinkList(); //初始化链表
void displayLinkList(LinkBook L); //显示图书信息
LinkBook getFinalNode(LinkBook L); //获取尾节点
void addBook(LinkBook L); //添加图书,这里是在最后添加图书
void deleteBook(LinkBook L, int num); //根据图书的编号num进行删除图书操作
void modifyBook(LinkBook L, int num); //根据图书的编号num对其进行修改
void findBook(LinkBook L, int num); //根据图书的编号num对其进行查找
void insertBook(LinkBook L, int i); //向指定的位置i插入一本书
void sortByNumber(LinkBook L); //根据图书的编号进行升序排序
void interface(); //程序交互界面
void outToTxt(LinkBook L); //将链表中的图书信息保存到txt文档中
函数的定义
见后面的function.c文件。
程序界面与功能演示
程序主界面:
添加功能演示:
删除功能演示:
修改功能演示:
查询功能演示:
插入功能演示:
插入后查询的结果:
排序功能演示:
这里默认的是根据图书的编号进行升序排序,这里采用的方法是冒泡排序算法,具体实现代码可以查看上面的函数定义或者后面的源码
排序前:
排序后:
保存为txt:
之后会在该项目所在的路径下面生成一个book.txt的文件,用于存放之前链表中 存放的图书信息,如下图所示:
完整代码
function.h文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct book
{
int number; //图书编号
char name[50]; //图书名
char lendData[50]; //借出日期
char condition[20]; //图书状态
int lendCount; //借阅次数
struct book *next;
}book, *LinkBook;
LinkBook initLinkList(); //初始化链表
void displayLinkList(LinkBook L); //显示图书信息
LinkBook getFinalNode(LinkBook L); //获取尾节点
void addBook(LinkBook L); //添加图书,这里是在最后添加图书
void deleteBook(LinkBook L, int num); //根据图书的编号num进行删除图书操作
void modifyBook(LinkBook L, int num); //根据图书的编号num对其进行修改
void findBook(LinkBook L, int num); //根据图书的编号num对其进行查找
void insertBook(LinkBook L, int i); //向指定的位置i插入一本书
void sortByNumber(LinkBook L); //根据图书的编号进行升序排序
void interface(); //程序交互界面
void outToTxt(LinkBook L); //将链表中的图书信息保存到txt文档中
function.c文件
#include"function.h"
LinkBook initLinkList() //初始化链表
{
LinkBook head = (LinkBook)malloc(sizeof(book));
head->next = NULL;
return head;
}
void displayLinkList(LinkBook L) //显示链表中图书的信息
{
printf("图书编号\t书 名\t\t\t借出日期\t\t图书状态\t\t借阅次数\n\n");
LinkBook p;
p = L->next; //p指向L头节点的下一个节点
if (p == NULL) //p为空,则说明链表内无图书信息
{
printf("暂无图书");
return;
}
while (p != NULL) //遍历输出链表中的图书信息
{
printf("%-8d\t%-20s\t%-20s\t%-20s\t%-8d\n", p->number, p->name, p->lendData, p->condition, p->lendCount);
//printf("%d\t%s\t%s\t%s\t%d\n", p->number, p->name, p->lendData, p->condition, p->lendCount);
p = p->next;
}
}
LinkBook getFinalNode(LinkBook L) //获取链表的尾节点
{
LinkBook p;
p =L;
while (p->next != NULL) //当p的下一个节点非空时,当前节点后移
p = p->next;
return p; //返回尾节点
}
void addBook(LinkBook L) //添加图书
{
LinkBook p,s;
int number; //图书编号
char name[50]; //图书名
char lendData[50]="2024-1-1"; //借出日期,添加进来默认为2024-1-1
char condition[20]="在馆"; //图书状态,添加进来默认在馆
int lendCount=0; //添加进来借阅次数默认为0
p = getFinalNode(L); //用p存放L的尾节点,目的是为了每次都在末尾插入图书信息
s = (LinkBook)malloc(sizeof(book));//s用来存放添加的图书信息
printf("请输入图书编号:");
scanf("%d", &number);
printf("\n请输入图书名:");
scanf("%s", name);
//s存放添加图书的信息
s->number = number;
strcpy(s->name, name);
strcpy(s->lendData, lendData);
strcpy(s->condition, condition);
s->lendCount = lendCount;
p->next = s; //将尾节点的下一个节点指向s
s->next = NULL;//令s的next指针为空,这样添加的图书就作为尾节点加入到原来的链表中
printf("\n图书已添加");
}
void deleteBook(LinkBook L, int num) //删除图书编号为num的图书信息
{
LinkBook p,q;
p = L;
while (p->next != NULL && p->next->number != num)//寻找图书编号为num的节点的前一个节点
p = p->next;
if (p->next == NULL && p->number != num) //如果找到最后一个节点都没有找到编号为num的节点,则说明不存在这样一本图书
{
printf("该图书不存在!");
return;
}
q = p->next; //用q存储编号为num的节点,p相当于是编号为num节点的前一个节点
p->next = q->next; //相当于直接跳过编号为num的节点,指向它的后一个节点,这样就达到了删除num节点的目的
printf("\n图书已被删除");
}
void modifyBook(LinkBook L, int num) //修改图书编号为num的图书信息
{
LinkBook p;
p = L;
int number; //图书编号
char name[50]; //图书名
char lendData[50]; //借出日期
char condition[20]; //图书状态
int lendCount; //借阅次数
while (p->next != NULL && p->number != num) //寻找编号为num的节点
p = p->next;
if (p->next == NULL && p->number != num)
{
printf("该图书不存在!");
return;
}
//输入修改的信息
printf("输入要修改的图书编号:");
scanf("%d", &number);
printf("输入要更改的书名:");
scanf("%s", name);
printf("输入要更改的借出日期:");
scanf("%s", lendData);
printf("输入要更改的图书状态:");
scanf("%s", condition);
printf("输入要更改的借阅次数:");
scanf("%d", &lendCount);
//找到之后,直接修改这个节点的信息
p->number = number;
strcpy(p->name, name);
strcpy(p->lendData, lendData);
strcpy(p->condition, condition);
p->lendCount = lendCount;
printf("\n图书已被修改");
}
void findBook(LinkBook L, int num) //查询编号为num的图书信息
{
printf("\n查询结果如下:\n");
LinkBook p;
p = L;
while (p->next != NULL && p->number != num)//寻找编号为num的节点
p = p->next;
if (p->next == NULL && p->number != num)
{
printf("该图书不存在!");
return;
}
//找到目标节点之后,打印出该图书的信息
printf("图书编号\t书 名\t\t\t借出日期\t\t图书状态\t\t借阅次数\n\n");
printf("%-8d\t%-20s\t%-20s\t%-20s\t%-8d\n", p->number, p->name, p->lendData, p->condition, p->lendCount);
}
void insertBook(LinkBook L, int i) //在指定位置i插入一本图书
{
//用于存储插入图书的信息
int count = 1; //用count来记录节点的位置
int number; //图书编号
char name[50]; //图书名
char lendData[50]; //借出日期
char condition[20]; //图书状态
int lendCount; //借阅次数
LinkBook p,s;
s = (LinkBook)malloc(sizeof(book));//s用于存放插入图书的信息
p = L;
while (p->next != NULL && count < i) //当指针还没有到达指定的位置i时,继续往后面移动
{
p = p->next;
count++; //每往后面移动一步,count加1记录一步
}
if (p->next == NULL && count < i)
{
printf("位置不存在!");
return;
}
//输入插入图书的信息
printf("输入要插入图书的编号:");
scanf("%d", &number);
printf("输入要插入图书的书名:");
scanf("%s", name);
printf("输入要插入图书的借出日期:");
scanf("%s", lendData);
printf("输入要插入图书的图书状态:");
scanf("%s", condition);
printf("输入要插入图书的借阅次数:");
scanf("%d", &lendCount);
//用s来存储插入图书的信息
s->number = number;
strcpy(s->name, name);
strcpy(s->lendData, lendData);
strcpy(s->condition, condition);
s->lendCount = lendCount;
s->next = p->next; //s的next指针指向目标位置后面的节点
p->next = s; //然后s充当目标位置i上的节点
printf("\n图书插入完毕!");
}
void sortByNumber(LinkBook L) //根据图书的编号进行升序排序
{
int flag; //用于标记是否已经排序完毕
LinkBook p, pre, tail;
tail = NULL; //tail指针来标记排好序的位置,tail往后的位置都是排好的,初始时没有排序,所以为空
while (1)
{
flag = 1;
//每次从L->next开始遍历,直到tail结束,pre是p的前驱节点
for (pre = L, p = L->next; p&&p->next != tail; pre = pre->next)
{
if (p->number > p->next->number) //前一个值大于后一个时
{
flag = 0; //flag设置为0,表示本轮循环发生交换
pre->next = p->next; //前驱直接指向后驱节点
p->next = p->next->next; //后驱节点指向后驱节点的后驱节点
pre->next->next = p;//相当于将当前节点变成其后驱节点
}
else
{
p = p->next;
}
}
if (flag)
break;
tail = p; //每一轮循环都有一个节点到正确的位置上,所以tail需要前移一个位置
}
printf("\n图书排序完毕");
}
void interface() //图书管理系统的交互界面设计
{
printf("\n\n=========图书管理系统=========");
printf("\n\n---------功能选择-----------");
printf("\n\n --->1.添加图书");
printf("\n --->2.删除图书");
printf("\n --->3.修改图书");
printf("\n --->4.查询图书");
printf("\n --->5.插入图书");
printf("\n --->6.排序图书");
printf("\n --->7.显示图书");
printf("\n --->8.保存为txt");
printf("\n --->9.退 出");
}
void outToTxt(LinkBook L) //将链表中存放的图书信息全部保存到.txt文件中
{
FILE *fp = NULL;
fp = fopen("book.txt", "a"); //打开book.txt,如果没有,会自动生成一个book.txt文件
if (fp == NULL)
{
printf("\n路径读取出错");
return;
}
//在book.txt中写入图书的各类信息的标题
fprintf(fp, "图书编号\t书 名\t\t\t借出日期\t\t图书状态\t\t借阅次数\n\n");
fflush(fp);
LinkBook p;
p = L->next;
while (p != NULL) //遍历链表,将每一条图书信息都写到book.txt文件中
{
fprintf(fp, "%-8d\t%-20s\t%-20s\t%-20s\t%-8d\n", p->number, p->name, p->lendData, p->condition, p->lendCount);
fflush(fp);
p = p->next;
}
fclose(fp);
}
main.c文件
#include"function.h"
int main()
{
int choice; //用于菜单操作的选择
int flag = 1; //用于终止程序
LinkBook L; //声明一个链表,用于存放图书信息
L = initLinkList(); //初始化链表
while (flag) //循环启动图书管理系统
{
int num; //用于存放修改、删除、查询的编号和插入的位置
interface(); //启动管理系统的交互界面
printf("\n请选择你的操作:");
scanf("%d", &choice);
switch (choice) //根据选择的操作,跳转到执行相应的功能
{
case 1: //执行添加图书操作
addBook(L);
break;
case 2: //执行删除图书操作
printf("请输入要删除图书的编号:");
scanf("%d", &num);
deleteBook(L, num); //删除指定图书编号的图书信息
break;
case 3: //执行修改图书操作
printf("请输入要修改的图书编号:");
scanf("%d", &num);
modifyBook(L, num); //修改指定图书编号对应的图书信息
break;
case 4: //执行查询图书操作
printf("请输入要查询的图书编号:");
scanf("%d", &num);
findBook(L, num); //根据给定的图书编号进行图书查询
break;
case 5: //执行指定位置插入图书
printf("请输入要插入的位置:");
scanf("%d", &num);
insertBook(L, num); //这里的num表示指定的位置
break;
case 6: //执行排序操作
sortByNumber(L); //根据图书的编号对其进行升序排序
break;
case 7: //执行显示图书操作
displayLinkList(L);
break;
case 8: //执行输出图书信息到.txt文件的操作
outToTxt(L);
break;
case 9: //退出系统,将flag设为0
flag = 0;
break;
default: //不是上述的功能,则提示出错
printf("\n输入错误,没有此功能");
break;
}
}
return 0;
}
需要源码的可以自行下载:C语言链表实现图书信息管理系统