单链表的排序(C++)
创作时间:
作者:
@小白创作中心
单链表的排序(C++)
引用
CSDN
1.
https://blog.csdn.net/m0_74091276/article/details/145839780
问题描述
给定一个节点数为n的无序单链表,需要将其按升序排序。数据范围:0 < n ≤ 100000,保证节点权值在[-109, 109]之内。要求空间复杂度为O(n),时间复杂度为O(nlogn)。
示例1
输入:
[1,3,2,4,5]
返回值:
{1,2,3,4,5}
示例2
输入:
[-1,0,-2]
返回值:
{-2,-1,0}
解题思路
本题采用归并排序算法对单链表进行排序。具体步骤如下:
Merge函数:用于合并两个已排序的链表。通过逐个节点比较的方式,将较小的节点接到结果链表中,最终返回合并后的链表头。
sortInList函数:通过快慢指针将链表拆分为两部分,递归地对每部分进行排序。具体来说,慢指针
left指向链表的头节点,快指针right和mid用于找到链表的中点,将链表分成两半,然后对每半部分递归排序,最后通过Merge函数合并两个有序链表。
代码实现
ListNode* Merge(ListNode* head1, ListNode* head2)
{
if(head1 == nullptr) return head2;
if(head2 == nullptr) return head1;
auto ret = new ListNode(-1);
auto head = ret;
while (head1 && head2) {
if (head1->val < head2->val) {
ret->next = head1;
head1 = head1->next;
}
else {
ret->next = head2;
head2 = head2->next;
}
ret = ret->next;
}
if (head1) {
ret->next = head1;
}
if (head2) {
ret->next = head2;
}
return head->next;
}
ListNode* sortInList(ListNode* head) {
if (head == nullptr || head->next == nullptr)
{
return head;
}
ListNode* left = head, *mid = head->next, *right = head->next;
while (right && right->next) {
left = left->next;
mid = mid->next;
right = right->next->next;
}
left->next = nullptr;
return Merge(sortInList(head), sortInList(mid));
}
代码解析
归并排序
如果链表为空或只有一个节点,直接返回链表;通过快慢指针将链表拆分成两部分,递归地对每部分进行排序,然后使用
Merge函数合并排序后的子链表,最终返回排序后的链表。ListNode* sortInList(ListNode* head) { if (head == nullptr || head->next == nullptr) { return head; } ListNode* left = head, *mid = head->next, *right = head->next; while (right && right->next) { left = left->next; mid = mid->next; right = right->next->next; } left->next = nullptr; return Merge(sortInList(head), sortInList(mid)); }合并两个已排序的链表
如果其中一个链表为空,直接返回另一个链表;否则,创建虚拟头节点
ret,逐个比较两个链表的节点,将较小的节点连接到结果链表。最后将剩余的部分连接到结果链表,返回合并后的链表。ListNode* Merge(ListNode* head1, ListNode* head2) { if(head1 == nullptr) return head2; if(head2 == nullptr) return head1; auto ret = new ListNode(-1); auto head = ret; while (head1 && head2) { if (head1->val < head2->val) { ret->next = head1; head1 = head1->next; } else { ret->next = head2; head2 = head2->next; } ret = ret->next; } if (head1) { ret->next = head1; } if (head2) { ret->next = head2; } return head->next; }
总结
本文介绍了如何使用归并排序对链表进行排序。首先通过Merge函数合并两个有序链表,再通过sortInList函数递归地拆分链表并排序。归并排序的优势在于其稳定性和O(nlogn)的时间复杂度,尤其适合链表结构的排序,因为它不需要额外的数组空间。通过快慢指针的拆分和递归合并,最终实现了一个高效的链表排序算法。
热门推荐
Windows系统电脑连不上WiFi:问题诊断与解决指南
道德一体,教化众生,无为而无不为
工业机器人职业发展路径与方向
甘特图中如何设定任务优先级别
八字中“官杀混杂”对男命有何影响?
国内首个!康为世纪幽门螺杆菌粪便耐药基因检测试剂盒获批上市
贝聿铭:跨文化的建筑之旅
日剧爱好者必看!10部豆瓣高分日剧盘点
每体:巴萨可能与法蒂续约至2030年,以分摊薪水
螺栓是什么?螺栓工作原理、类型和安装方法详解
供应链下的采购成本管理与供应商选择策略:最新趋势解读
大学生如何成为IT项目经理
广西凭祥:边境贸易、跨境电商与旅游服务业的发展潜力分析
宝鸡城,藏着“最早的中国”
父亲犯罪子女是否需要赔偿?法律这样规定
建筑师谈刘家琨获奖:应该放在行业转型的大背景中去看待
解决Win11输入法切换失效的实用指南
电脑卡了不动了怎么办按哪个键恢复?一文全搞定!
如何理解金融市场中的风险与回报?这种关系如何平衡和优化?
洛阳天池山风景区:穿越历史遗迹,领略自然奇观
戴水晶吉祥物,五行属性真的重要吗?
夏天吃莲子好吗?功效与注意事项全解析
研究开发新型无创、高精度口腔癌早期诊断工具
梅奥诊所:明尼苏达州口腔癌和重建专科门诊
阿维菌素、甲维盐2024年市场表现亮眼,多重因素支撑连涨潜力
钱是有灵性的,这3个聚财方法,让你越来越富有
防控近视「99 训练操」 | 近视防控「防」什么,这篇文章终于讲清楚了
高温合金在航空航天领域的应用及发展状况
如何高效进行数据看板搭建?掌握这些技巧让你事半功倍!
学会慢下来奔跑,你会发现跑步带给你的更多好处