当前位置:网站首页>LeetCode148:排序链表 归并排序,思路清晰,C语言练习看过来!
LeetCode148:排序链表 归并排序,思路清晰,C语言练习看过来!
2022-08-09 09:29:00 【农场主er】
题目描述
在 O(n log n)
时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
思路分析
在排序算法中,时间复杂度满足要求的并不多,而单链表的特殊之处又是无法从后往前遍历,所以想到了2路归并排序。
逐级的分裂和合并是由递归完成的,只需要写出找到链表中间节点的程序findMid(struct ListNode* head)
和将两个链表合并的程序merge(struct ListNode* head, struct ListNode* midNode)
即可
C语言代码
//建立链表结点
struct ListNode
{
int val;
struct ListNode *next;
};
//找到中间节点
struct ListNode* findMid(struct ListNode* head) {
//一次遍历找到midNode,往往需要两个指针
struct ListNode* fastNode = head;
struct ListNode* slowNode = head;
//注意非空的判断
while (fastNode != NULL && fastNode->next != NULL) {
fastNode = fastNode->next->next;
if (fastNode != NULL)
slowNode = slowNode->next;
}
//对应数组中的第(length-1)/2个元素
return slowNode;
}
//对两个链表进行合并
struct ListNode* merge(struct ListNode* head, struct ListNode* midNode) {
//增加头节点便于对表头进行操作
struct ListNode* result = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* copy = (struct ListNode*)malloc(sizeof(struct ListNode));
result = copy;
while (head != NULL && midNode != NULL) {
if (head->val < midNode->val) {
copy->next = head;
head = head->next;
}
else {
copy->next = midNode;
midNode = midNode->next;
}
copy = copy->next;
}
//循环结束之后可能还有剩余节点没有加入
if (head != NULL)
copy->next = head;
if (midNode != NULL)
copy->next = midNode;
return result->next;
}
//合并排序
struct ListNode* sortList(struct ListNode* head) {
if (head == NULL)
return NULL;
struct ListNode* midNode = findMid(head);
//递归结束判断条件
if (midNode->next == NULL)
return midNode;
struct ListNode* one = sortList(midNode->next);
//一定要断开节点,便于merge
midNode->next = NULL;
struct ListNode* two = sortList(head);
return merge(one, two);
}
复杂度分析
- 时间复杂度:
O(n log n)
- 空间复杂度:这个有点迷惑,因为用到了递归,应该不是常数级,而是
O(log n)
,所以没有达到题目的要求,非递归的方法我暂时没想出来
欢迎大家交流指正~
边栏推荐
猜你喜欢
接口测试的基础流程和用例设计方法你知道吗?
Ontology Development Diary 01-Jena Configuration Environment Variables
Sweet alert
Ontology Development Diary 03 - When debugging is in progress
电脑硬件基础知识科普
QT sets the icon of the exe executable
接口测试的概念、目的、流程、测试方法有哪些?
latex中复杂公式换行等号对齐
"The camera can't be used" + win8.1 + DELL + external camera + USB drive-free solution
Anti App so层对抗分析
随机推荐
6.File类
接口测试的概念、目的、流程、测试方法有哪些?
常用功能测试的检查点与用例设计思路
有返回值的函数
手机APP测试流程规范和方法你知道多少?
6.Map接口与实现类
Go-接口的那些事
map去重代码实现
一个项目的整体测试流程有哪几个阶段?测试方法有哪些?
软件测试面试中,面试官问你一些比较“刁难”的问题你会怎么回答
WAVE SUMMIT 2022深度学习开发者峰会
单元测试是什么?怎么写?主要测试什么?
本体开发日记03-排错进行时
Anti App so层对抗分析
秒拍app分析
GBase数据库中,源为 oracle 报出“ORA-01000:超出打开游标最大数”
Go-goroutine 的那些事
Golang Protobuf 处理
8.递归遍历和删除案例
1.线程简介