当前位置:网站首页>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),所以没有达到题目的要求,非递归的方法我暂时没想出来
欢迎大家交流指正~
边栏推荐
猜你喜欢

搭建Tigase进行二次开发

手机APP测试流程规范和方法你知道多少?

A Practical Guide to Building OWL Ontologies using Protege4 and CO-ODE Tools - Version 1.3 (7.4 Annotation Properties - Annotation Properties)
全网最全的软件测试基础知识整理(新手入门必学)

Summary of steps and methods for installing and uninstalling test cases that you must read
软件测试流程包括哪些内容?测试方法有哪些?

2048小游戏成品源码
自动化测试简历编写应该注意哪方面?有哪些技巧?

你一定要看的安装及卸载测试用例的步骤及方法总结

命令行查询数据库
随机推荐
5.Set接口与实现类
列表
可以写进简历的软件测试项目实战经验(包含电商、银行、app等)
接口性能测试方案设计方法有哪些?要怎么去写?
测试计划包括哪些内容?目的和意义是什么?
本体开发日记02-sparql简单查询
Sweet alert
MySQL Leak Detection and Filling (2) Sorting and Retrieval, Filtering Data, Fuzzy Query, Regular Expression
接口测试的概念、目的、流程、测试方法有哪些?
迭代
2.线程创建
What are the basic concepts of performance testing?What knowledge do you need to master to perform performance testing?
恶意软件查杀工具分享
接口设计
字符串
4. Generics and Utilities
Ontology Development Diary 03 - When debugging is in progress
4.泛型和工具类
软件测试面试常见问题及答案(发散思维、接口、性能、概念、)
4. Character stream