原题链接:[编程入门]链表合并
解题思路:
自定义函数实现功能模块化:
1、创捷链表createList
2、创建节点creatNode
3、插入节点insertNodeByHead(这里用的是头插入)
4、链表合并mergeList
5、链表排序sortList(选择排序法)
6、链表打印printList
注意事项: 看代码注释就够啦哈哈哈
参考代码:
#include <stdio.h>
#include <stdlib.h>
struct student{
int id; //学号
int score; //成绩
};
struct Node{
struct student data; //数据域
struct Node* next; //指针域
};
//创捷链表
struct Node* createList()
{
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); //动态申请内存
headNode -> next = NULL;
return headNode;
}
//创建节点
struct Node* createNode(struct student data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //动态申请内存
newNode -> data = data; //初始化
newNode -> next = NULL;
return newNode;
}
//插入节点
void insertNodeByHead(struct Node* headNode, struct student data) //头插法:每次插入节点都是插入在headNode和headNode->next之间
{
struct Node* newNode = createNode(data); //调用创建节点函数
newNode -> next = headNode -> next; //新节点指向的下一个是原头节点的下一个
headNode -> next = newNode; //头节点指向的下一个节点是新节点
}
//链表连接
void mergeList(struct Node* headNode1, struct Node* headNode2)
{
struct Node* pMove = headNode1; //移动指针变量找到list1的尾节点,然后与list2连接
while(pMove -> next != NULL) //while寻找尾节点
{
pMove = pMove -> next; //若不是空,则说明不是尾节点,pMove不断后移,当pMove为空(NULL)时,说明此时pMove所在节点就是尾节点
}
headNode2 = headNode2 -> next; //list2的头节点是没有数据的,所以连接的是list2->next.
pMove -> next = headNode2; //实现链表的连接功能
}
//链表排序
void sortList(struct Node* headNode, struct student data)
{
struct Node* turn = headNode -> next; //turn用于外循环,遍历每个节点
struct Node* move = headNode -> next -> next; //move用于内循环,遍历turn后面未排序的所以节点
struct Node* min = headNode -> next; // min用于定位内循环中当前的最小的学号的节点
while(turn -> next != NULL) //外循环
{
min = turn; //每一次内循环遍历前都要初始化,假使turn就是当前最小的学号的节点
while(move != NULL)
{
if(move -> data.id < min -> data.id) //判断move里的学号与min里的学号的大小
{
min = move;
}
move = move -> next; //move不断后移遍历
}
if(min != turn)
{
struct student temp = min -> data; //数据交换
min -> data = turn -> data;
turn -> data = temp;
}
turn = turn -> next; //每次内循环结束后,turn都要向后移动一个节点,开始排序第二个数据…………
move = turn -> next; //move指向的节点永远是turn指向的节点的下一个
}
}
//链表打印
void printList(struct Node* headNode, struct student data)
{
struct Node* pMove = headNode -> next;
while(pMove != NULL)
{
printf("%d\t%d\n", pMove -> data.id, pMove -> data.score);
pMove = pMove -> next;
}
}
int main()
{
struct student information; //定义结构体变量information用于暂时存放数据
struct Node* list1 = createList(); //调用创建链表函数
struct Node* list2 = createList();
int N, M;
scanf("%d %d", &N, &M);
for(int i = 0; i < N; i ++) //获取list1的数据
{
scanf("%d %d", &information.id, &information.score);
insertNodeByHead(list1, information); //调用插入节点函数
}
for(int j = 0; j < M; j ++) //获取list2的数据
{
scanf("%d %d", &information.id, &information.score);
insertNodeByHead(list2, information);
}
mergeList(list1, list2); //调用链表连接函数
sortList(list1, information); //调用排序函数
printList(list1, information); //打印验证
return 0;
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复