IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C/C++:链表的基本操作(核心代码:分部解析中有注释的部分) -> 正文阅读

[数据结构与算法]C/C++:链表的基本操作(核心代码:分部解析中有注释的部分)

我以一个图书管理系统的题目为例

可以只看核心代码就好(分部解析中有注释的部分)


目录

一、例题题目

二、完整代码

三、分部解析(链表的各种基本操作)

1-图书信息录入(初始化、创建链表)

初始化链表

创建链表

运行结果

?

2-图书信息排序【链表排序(改变链表节点的连接顺序,实现选择插入排序)】

3-图书信息插入(链表的插入)

4-图书信息修改

5-图书信息删除(链表结点删除)

6-图书信息查找

7-图书信息统计

?8-退出系统

四、题目中的部分函数

遍历链表

得到书本实例



一、例题题目

使用链表编程实现图书信息(书名、单价)管理

功? 能:

1.图书信息录入:从键盘输入n(n<10)本书的书名和单价用于构造图书链表,然后输出所有图书信息;

2.图书信息排序:按照单价从高到低的顺序进行排序后输出图书信息;

3.图书信息插入:实现新增图书信息(图书信息插入链表后,单价排序保持降序)并输出图书信息;

4.图书信息查找:实现图书按名查找并输出结果;

5.图书信息删除:实现按书名删除图书信息后输出图书信息;

6.图书信息修改:实现按书名修改图书单价后输出图书信息;

7.图书信息统计:实现统计图书数量及图书总价并输出结果。

要? 求:1.编写函数实现各功能要求(可写一个函数用于输出图书信息);

2.在主函数中设计一个菜单,选择相关功能后按要求输入数据并调用各函数实现;

1-图书信息录入

2-图书信息排序

3-图书信息插入

4-图书信息修改

5-图书信息删除

6-图书信息查找

7-图书信息统计

8-退出系统

请输入功能编号:



二、完整代码(较长可以先不看,建议直接看分部解析的核心代码)

这是这道例题的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Book {
	char name[50];
	float price;
	struct Book* next;
}Book;
void menu();
Book* initLinkList();
void createLinkList(Book* head);
void sortLnkList(Book* head);
void insetBook(Book* head);
void changeBook(Book* head);
Book* findBook(Book* head, char* name);
void countBook(Book* head);
void showList(Book* head);
Book getBook();
void deleteBook(Book* head);
int main() {
	menu();
	Book* head = initLinkList();//得到表头
	if (head == NULL) {
		printf("空间不足,初始化链表失败!\n");
		return 0;
	}
	int operationCode;
	while (1) {
		printf("\n请输入功能编号:");
		scanf("%d", &operationCode);
		switch (operationCode)
		{
		case 1://1-图书信息录入
			createLinkList(head);
			printf("\n图书信息录入完成!\n");
			showList(head);
			break;
		case 2://2-图书信息排序
			sortLnkList(head);
			showList(head);
			break;
		case 3://3-图书信息插入
			insetBook(head);
			showList(head);
			break;
		case 4://4-图书信息修改
			changeBook(head);
			break;
		case 5://5-图书信息删除
			deleteBook(head);
			break;
		case 6://6-图书信息查找
			printf("请输入您想查找的书名:");
			char name[50];
			scanf("%s", name);
			if (findBook(head, name) != NULL) {
				Book* book = findBook(head,name);
				printf("\n查找结果:%s\t\t%.2f\n", book->name, book->price);
			}
			else {
				printf("\n查无此书!\n");
			}
			break;
		case 7://7-图书信息统计
			countBook(head);
			break;
		case 8://8-退出系统
			printf("\n已退出\n");
			exit(1);
			break;
		default:
			printf("\n请输入正确的功能编号!\n");
			break;
		}
	}
	return 0;
}
void menu() {
	printf("\
	1 - 图书信息录入\n\
	2 - 图书信息排序\n\
	3 - 图书信息插入\n\
	4 - 图书信息修改\n\
	5 - 图书信息删除\n\
	6 - 图书信息查找\n\
	7 - 图书信息统计\n\
	8 - 退出系统\n");
}
Book* initLinkList() {
	Book* head = (Book*)malloc(sizeof(Book));
	if (head != NULL) {
		strcpy(head->name, "thisHead");
		head->price = 0;
		head->next = NULL;
		return head;
	}
	return NULL;
}
void insetBook(Book* head) {
	Book* p = head;
	Book* q = (Book*)malloc(sizeof(Book));
	if (q != NULL) {
		*q = getBook();
		while (p->next->price > q->price) {
			p = p->next;
			if (p->next == NULL) {
				break;
			}
		}
		q->next = p->next;
		p->next = q;
	}
	else {
		printf("空间不足!\n");
	}
}
Book getBook() {
	Book book;
	char name[50];
	float price;
	printf("请输入书名和单价,用空格也隔开:\n");
	scanf("%s%f", name, &price);
	strcpy(book.name, name);
	book.price = price;
	return book;
}
void sortLnkList(Book* head) {
	Book* inset = head,*p,*q;
	while (1) {
		if (inset->next == NULL)break;
		p = inset;
		while (1){
			if (p->next == NULL)break;
			q = p->next;
			if (q->price > inset->next->price) {
				p->next = q->next;
				q->next = inset->next;
				inset->next = q;
			}
			else {
				p = p->next;
			}
		}
		inset = inset->next;
	}
}
void showList(Book* head) {
	Book* p = head->next;
	printf("所有图书信息如下:\n书名\t\t单价\n");
	for (p; p != NULL; p = p->next) {
		printf("%s\t\t%.2f\n", p->name, p->price);
	}
}
void createLinkList(Book* head) {
	int bookNumber;
	printf("请输入图书数量:");
	scanf("%d", &bookNumber);
	for (int i = 0; i < bookNumber; i++) {
		printf("第%d本 ", i + 1);
		Book* p = (Book*)malloc(sizeof(Book));
		if (p != NULL) {
			*p = getBook();
			p->next = head->next;
			head->next = p;
		}
		else {
			printf("空间不足!\n");
		}

	}
}
Book* findBook(Book* head, char* name) {
	Book* p = head->next;
	for (p; p != NULL; p = p->next) {
		if (strcmp(p->name, name) == 0) {
			return p;
		}
	}
	return NULL;
}
void changeBook(Book* head) {
	float changePrice;
	printf("请输入您想修改图书信息的书名:");
	char name[50];
	scanf("%s", name);
	Book* p = findBook(head, name);
	if (p != NULL) {
		printf("该图书信息为:%s\t\t%.2f\n", p->name, p->price);
		printf("输入修改的单价:");
		scanf("%f", &changePrice);
		p->price = changePrice;
		printf("\n修改成功:%s\t\t%.2f\n\n", p->name, p->price);
		sortLnkList(head);
		showList(head);
	}
	else {
		printf("\n暂无该图书信息!\n");
	}
}
void deleteBook(Book* head) {
	printf("请输入要删除的图书书名:");
	char name[50];
	scanf("%s", name);
	if (findBook(head, name) != NULL) {
		Book* p = head;
		for (p->next; p->next != NULL; p = p->next) {
			if (strcmp(p->next->name, name) == 0) {
				Book* deleteTag = p->next;
				p->next = p->next->next;
				free(deleteTag);
				if (p->next == NULL)break;
			}
		}
		printf("\n删除成功!\n");
		showList(head);
	}
	else {
		printf("\n无此书!\n");
	}
}
void countBook(Book* head) {
	Book* p = head->next;
	int totalBookNumber = 0;
	float totalPrice = 0;
	for (p; p != NULL; p = p->next) {
		totalBookNumber++;
		totalPrice += p->price;
	}
	printf("\n统计结果如下:\n");
	showList(head);
	printf("图书总数量:%d\n图书总价为:%.2f\n", totalBookNumber, totalPrice);
}


三、分部解析(链表的各种基本操作)

1-图书信息录入(初始化、创建链表

初始化链表

//先定义一个结构体用作结点
typedef struct Book {
	char name[50];
	float price;
	struct Book* next;
}Book;
Book* head = initLinkList();//得到头结点
//生成并返回一个头结点
Book* initLinkList() {
	Book* head = (Book*)malloc(sizeof(Book));//请求一块空间
	if (head != NULL) {
        //初始化头结点
		strcpy(head->name, "thisHead");//非必要
		head->price = 0;//非必要
		head->next = NULL;//必要
		return head;
	}
	else {
		printf("空间不足,初始化链表失败!\n");
		return NULL;
	}
}

创建链表

void createLinkList(Book* head) {
	int bookNumber;
	printf("请输入图书数量:");
	scanf("%d", &bookNumber);
	for (int i = 0; i < bookNumber; i++) {
		printf("第%d本 ", i + 1);
		Book* p = (Book*)malloc(sizeof(Book));
		if (p != NULL) {
			*p = getBook();//用自定义函数getBook()得到一本书的实例
			p->next = head->next;//从头插入书本结点
			head->next = p;
		}
		else {
			printf("空间不足!\n");
		}

	}
}

运行结果


2-图书信息排序【链表排序(改变链表节点的连接顺序,实现选择插入排序)】

void sortLnkList(Book* head) {
    /*inset用于定位插入位置(已排序队列的队尾)
      p用于遍历链表
      q用于临时保存p->next的地址,改变链表节点的连接顺序时得用到,q=p->next*/
	Book* inset = head,*p,*q;
	while (1) {
		if (inset->next == NULL)break;//排序完成
		p = inset;
		while (1){
			if (p->next == NULL)break;//一轮遍历结束
			q = p->next;
            /*改变链表节点的连接顺序
            每次排序都从未排序的队列中,找最大的元素,插到已排序队列(降序)的队尾*/
			if (q->price > inset->next->price) {
                /*如果发生了插入p就已被迫后移
                无需执行p = p->next;*/
				p->next = q->next;
				q->next = inset->next;
				inset->next = q;
			}
			else {
                //如果未发生插入,则要我们自己去移动指针p
				p = p->next;
			}
		}
        //始终定位在已排序队列的队尾
		inset = inset->next;
	}
}

运行结果


3-图书信息插入(链表的插入)

void insetBook(Book* head) {
	Book* p = head;//p指向表头,用于从表头开始遍历链表
	Book* q = (Book*)malloc(sizeof(Book));
	if (q != NULL) {
		*q = getBook();//用自定义函数getBook()得到一本书的实例
        //找到插入位置
		while (p->next->price > q->price) {
			p = p->next;
			if (p->next == NULL) {
				break;
			}
		}
        //进行插入
		q->next = p->next;
		p->next = q;
	}
	else {
		printf("空间不足!\n");
	}
}

运行结果


4-图书信息修改

? ? ? ? 这个比较简单就不贴代码了:

(1)先找到要修改的目标结点

(2)修改数据

运行结果


5-图书信息删除(链表结点删除)

这个我觉得挺有细节的

void deleteBook(Book* head) {
	printf("请输入要删除的图书书名:");
	char name[50];
	scanf("%s", name);
	if (findBook(head, name) != NULL) {
		Book* p = head;
		for (p->next; p->next != NULL; p = p->next) {
            //注意这里比较的是p->next而不是p
			if (strcmp(p->next->name, name) == 0) {
				Book* deleteTag = p->next;//找到要删除的目标结点用deleteTag暂存
				p->next = p->next->next;//将到要删除的目标结点移出链表
				free(deleteTag);//释放目标结点的空间,清空数据
				if (p->next == NULL)break;/*如果p是最后一个结点就跳出,
                                          不然循环体for执行p = p->next,
                                          p为空指针(p->next != NULL语句报错)*/
			}
		}
		printf("\n删除成功!\n");
		showList(head);
	}
	else {
		printf("\n无此书!\n");
	}
}

运行结果


6-图书信息查找

这个不是很难

Book* findBook(Book* head, char* name) {
	Book* p = head->next;
    //从头到尾遍历链表
	for (p; p != NULL; p = p->next) {
		if (strcmp(p->name, name) == 0) {
			return p;
		}
	}
	return NULL;
}

运行结果


7-图书信息统计

? ? ? ? 这个也比较简单,就是遍历一遍链表

运行结果


?8-退出系统

运行结果



四、题目中的部分函数

遍历链表

void showList(Book* head) {
	Book* p = head->next;
	printf("所有图书信息如下:\n书名\t\t单价\n");
	for (p; p != NULL; p = p->next) {
		printf("%s\t\t%.2f\n", p->name, p->price);
	}
}

得到书本实例

Book getBook() {
	Book book;
	char name[50];
	float price;
	printf("请输入书名和单价,用空格也隔开:\n");
	scanf("%s%f", name, &price);
	strcpy(book.name, name);
	book.price = price;
	return book;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-19 18:27:38  更:2021-12-19 18:28:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:21:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码