- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- //创建结构体及其成员
- typedef struct Node {
- int num;//编号
- char name[20];//书名
- char author[20];//作者
- int isexsit;//数量
- float price;//价格
- struct Node *next;//指针域
- } S;//结构体定义为S
- //各函数定义
- void choose();
-
- void menu(); //菜单函数
- S *create();//创建链表函数
- void print(S *);//输出链表函数
- void pop_sort(S *);//排序
- void insert(S *);//插入节点函数
- void del(S *);//删除节点函数
- void search1(S *);//书名查找节点函数
- void search2(S *);//作者查找节点函数
- void search3(S *);//编号查找
- void mod(S *);//修改图书信息
- //主函数
- int main() {
- choose();
- }
-
- void choose() {
- S *head;
- int n, a = 1;//n用来控制选择操作类型,a控制循环,以-1终止
- while (a > 0) {
- menu();//显示菜单
- printf("选择你想使用的功能:");
- scanf("%d", &n);//选择操作
- switch (n)//各操作数字对应菜单数字,通过n确定操作类型
- {
- case 1://创建
- head = create();
- break;
- case 2://输出
- printf("图书信息为(按价格排序后)\n");
- pop_sort(head);
- printf("编号\t书名\t作者\t数量\t价格\n");
- print(head);
- break;
- case 3://插入
- insert(head);
- printf("插入后\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- print(head);
- break;
- case 4://删除
- del(head);
- printf("删除后\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- print(head);
- break;
- case 5://书名查找
- search1(head);
- break;
- case 6://作者查找
- search2(head);
- break;
- case 7://编号查找
- search3(head);
- break;
- case 8://修改
- mod(head);
- pop_sort(head);
- printf("图书信息为\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- print(head);
- break;
- default:
- a = -1;//跳出循环条件
- break;
- }
- }
- }
-
- //菜单模块直接显示
- void menu() {
- printf("\n\n");
- printf("\t\t 欢迎使用图书管理系统\n");
- printf("\t\t|----------SCORE-----------|\n");
- printf("\t\t|\t1.创建图书 |\n");
- printf("\t\t|\t2.展示图书信息 |\n");
- printf("\t\t|\t3.添加图书信息 |\n");
- printf("\t\t|\t4.删除图书 |\n");
- printf("\t\t|\t5.按图书名搜索 |\n");
- printf("\t\t|\t6.按作者名搜索 |\n");
- printf("\t\t|\t7.按图书编号搜索 |\n");
- printf("\t\t|\t8.修改图书信息 |\n");
- printf("\t\t|\t9.退出程序 |\n");
- printf("\t\t|--------------------------|\n");
- printf("\t\t\tchoice(1-9):\n");
- }
-
- //创建链表模块
- S *create() {
- S *head, *p, *q;//定义指针
- int i;
- head = (S *) malloc(sizeof(S));//头节点开辟空间
- head->next = NULL;//置空头节点的指针域
- q = head;//q指针记录头节点的地址
- p = head->next;//p指针记录头节点的指针域的地址
- printf("请输入图书编号,图书名,作者,图书数量,价格,最后输入0结束\n");
- int num;
- scanf("%d", &num);
- while (num != 0)//输入书籍编号输入为零停止循环
- {
- p = (S *) malloc(sizeof(S));//p指针开辟空间
- //输入各成员
- p->num = num;
- scanf("%s %s %d %f", p->name, p->author, &p->isexsit, &p->price);
- p->next = NULL;//置空p节点的指针域
- q->next = p;//p,q节点连接
- q = p;//q指针后移
- printf("请输入图书编号,图书名,作者,图书数量,价格,最后输入0结束\n");
- scanf("%d", &num);
- }
- return head;//返回链表的起始地址
- }
-
- //插入节点模块(可多个插入)
- void insert(S *head) {
- int i, num, flag = 1;//flag实现判断指针是否到达最后一个节点
- S *p, *q, *r; //定义指针便于插入操作
- printf("请输入一本图书的信息:\n");
- printf("请输入图书的编号,输入0结束\n");
- scanf("%d", &num);
- while (num != 0)//输入编号不为零时循环,以零终止,可实现多个插入
- {
- r = (S *) malloc(sizeof(S));//为r开辟空间
- r->next = NULL;//置空r的指针域
- r->num = num;
- printf("请输入图书名,作者,图书数量,图书价格\n");
- scanf("%s %s %d %f", r->name, r->author, &r->isexsit, &r->price);
- q = head;//q指针记录头节点的地址
- p = head->next;//p指针记录头节点的指针域的地址
- while (q->next != NULL && p->price < r->price)//循环条件:当q->next不为空,以及按价格排序插入
- {
- p = p->next;//p指针后移
- q = q->next;//q指针后移
- if (q->next == NULL)//这个判断防止q->next为空时,在执行循环是出现野指针使程序出错
- {
- p = NULL;//防止出现野指针p
- q->next = r;//连接节点
- r->next = NULL;//置空r指针域
- flag = 0;//到达最后一个节点更改flag
- break;
- }
- }
- if (flag)//判断是否到达最后一个节点,为真执行该操作
- {
- r->next = p;
- q->next = r;
- //实现将r节点插入链表
- }
- printf("请输入图书编号,输入0结束\n");
- scanf("%d", &num);
- }
- }
-
- //删除节点模块
- void del(S *head) {
- S *p, *q;//定义指针
- int b;//用于输入编号查找删除
- p = head;//p记录头节点的地址
- q = head->next;//q记录头节点的指针域的地址
- printf("请输入你想要删除的图书编号:");
- //输入编号
- scanf("%d", &b);
- while (q != NULL)//q不为空时执行循环
- {
- if (q->num == b)//判断是否找到输入的编号
- //为真时
- {
- p->next = q->next;//断开q节点
- free(q);//释放q节点neicun
- q = NULL; //置空q指针防止出现野指针
- } else {
- //判断为假时
- p = p->next;//p指针后移
- q = q->next;//q指针后移
- }
- }
- if (p == NULL)//当查找到最后一个节点还未查到要删除的编号时,输出输入错误
- printf("输入错误\n");
- }
-
- //书名查找模块
- void search1(S *head) {
- S *p;//定义指针
- char name1[20];//定义name1用于输入查找书名
- printf("请输入你要搜素的书名:");
- //输入查找书名
- scanf("%s", name1);
- p = head->next;
- while (p != NULL) {
- if (strcmp(p->name, name1) == 0)//判断是否找到书籍
- {
- //为真时,输出信息
- printf("书籍信息\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit, p->price);
- break;
- } else
- //为假时
- p = p->next;//指针后移
- }
- if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出输入错误
- printf("输入错误\n");
- }
-
- //作者查找模块
- void search2(S *head) {
- S *p;//定义指针
- char name2[20];//定义name2用于输入查找书籍
- printf("输入你想要查询的作者:");
- //输入查找作者
- scanf("%s", name2);
- p = head->next;
- while (p != NULL) {
- if (strcmp(p->author, name2) == 0)//判断是否找到书籍
- {
- //为真时,输出信息
- printf("书籍信息\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit, p->price);
- break;
- } else
- //为假时
- p = p->next;//指针后移
- }
- if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出输入错误
- printf("输入错误\n");
- }
-
- //编号查找
- void search3(S *head) {
- S *p;//定义指针
- int num1;//定义num1用于输入查找书籍
- printf("请输入你要搜索的图书编号:");
- //输入查找编号
- scanf("%d", &num1);
- p = head->next;
- while (p != NULL) {
- if (p->num == num1)//判断是否找到书籍
- {
- //为真时,输出信息
- printf("书籍信息\n");
- printf("编号\t书名\t作者\t数量\t价格\n");
- printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit, p->price);
- break;
- } else
- //为假时
- p = p->next;//指针后移
- }
- if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出ERROR INPUT
- printf("输入错误\n");
- }
-
- //修改信息模块
- void mod(S *head) {
- S *p;//定义指针
- int num1, num2, isexsit1;//定义num1用于输入查找书籍修改信息,num2用于修改
- char name1[20], author1[20];
- float price1;
- printf("请输入你要修改的图书编号:");
- //输入要修改的图书编号
- scanf("%d", &num1);
- p = head->next;
- while (p != NULL) {
- if (p->num == num1)//判断是否找到书籍
- {
- printf("请再次输入 图书编号,书名,作者,图书数量 ,价格\n");
- //为真时,重输图书信息
- scanf("%d %s %s %d %f", &num2, name1, author1, &isexsit1, &price1);
- p->num = num2;
- strcpy(p->name, name1);
- strcpy(p->author, author1);
- p->isexsit = isexsit1;
- p->price = price1;
- break;
- } else
- //为假时
- p = p->next;//指针后移
- }
- if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出输入错误
- printf("输入错误\n");
- }
-
- void pop_sort(S *head) //链表冒泡排序
- {
- //排序中没有修改头节点指针值,只是修改指针内容head->next的值
- S *pre, *p, *tail, *temp;
- tail = NULL;
- pre = head;
- while ((head->next->next) != tail)//(head->next)!=tail同样适用 ,多执行最后一个步比较
- {
- p = head->next;
- pre = head;
- while (p->next != tail) {
- if ((p->price) > (p->next->price)) {
- pre->next = p->next; //交换节点方法
- temp = p->next->next;
- p->next->next = p;
- p->next = temp;
- p = pre->next; //p回退一个节点
- }
- p = p->next; //p再前进一个节点
- pre = pre->next;
- }
- tail = p;
- }
- }
-
- //输出链表模块
- void print(S *head) {
- int i;
- S *p = head->next;
- while (p)//当p不为空的时候执行
- {
- printf("%d\t%s\t%s\t%d\t%.2f\n", p->num, p->name, p->author, p->isexsit, p->price);
- printf("\n");
- p = p->next;//指针后移
- }
- }