当前位置:网站首页>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)
,所以没有达到题目的要求,非递归的方法我暂时没想出来
欢迎大家交流指正~
边栏推荐
猜你喜欢
随机推荐
1.流的概念
性能测试的基本概念是什么?做好性能测试需要掌握哪些知识?
一个项目的整体测试流程有哪几个阶段?测试方法有哪些?
Do you know the principles of test cases and how to write defect reports?
1.线程简介
类 对象 属性 方法 类的成员
seata处理分布式事务
软件测试个人求职简历该怎么写,模板在这里
Firebase+Facebook 授权 web 登录提示域名验证或跳转错误
性能测试包括哪些方面?分类及测试方法有哪些?
2048小游戏成品源码
Summary of steps and methods for installing and uninstalling test cases that you must read
2. Thread creation
BlockingQueue理论普
恶意软件查杀工具分享
Another implementation of lateral view explode
接口测试主要测试哪方面?需要哪些技能?要怎么学习?
Thread,Runnable,ExecutorService线程池控制下线程量
static_assert报错为什么?
关于一次性通过CISSP考试的一点经验分享