我们可以试用归并排序解决:
对链表归并排序的过程如下。

找到链表的中点,以中点为分界,将链表拆分成两个子链表。寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。

对两个子链表分别排序。

将两个排序后的子链表合并,得到完整的排序后的链表

上述过程可以通过递归实现。递归的终止条件是链表的节点个数小于或等于 1,即当链表为空或者链表只包含 1 个节点时,不需要对链表进行拆分和排序。


class Solution {public:ListNode* sortList(ListNode* head) {return sortList(head, nullptr);}ListNode* mergesort(ListNode* head, ListNode* tail) {if (head == nullptr) {return head;}if (head->next == tail) {head->next = nullptr;return head;}ListNode* slow = head, * fast = head;while (fast != tail) {slow = slow->next;fast = fast->next;if (fast != tail) {fast = fast->next;}}return merge( mergesort(head, slow),  mergesort(slow, tail));}ListNode* merge(ListNode* head1, ListNode* head2) {ListNode* dummyHead = new ListNode(0);ListNode* temp = dummyHead, * temp1 = head1, * temp2 = head2;while (temp1 != nullptr && temp2 != nullptr) {if (temp1->val <= temp2->val) {temp->next = temp1;temp1 = temp1->next;}else {temp->next = temp2;temp2 = temp2->next;}temp = temp->next;}if (temp1 != nullptr) {temp->next = temp1;}else if (temp2 != nullptr) {temp->next = temp2;}return dummyHead->next;}
};

快速排序不能随机选取节点,时间复杂度太高所以会超时

class Solution {public static ListNode sortList(ListNode head) {return quickSort(head ,null);}public static ListNode quickSort(ListNode head ,ListNode end){if(head ==end || head.next ==end) return head;ListNode lhead = head ,utail = head ,p = head.next;while (p != end){ListNode next = p.next;if(p.val < head.val){//头插p.next = lhead;lhead = p;}else { //尾插utail.next = p;utail = p;}p = next;}utail.next = end;ListNode node = quickSort(lhead, head);head.next =  quickSort(head.next, end);return node;}
}

C++链表排序(归并法+快速排序)相关推荐

  1. C语言版--单链表排序,冒泡排序,选择排序,插入排序,快速排序,应有尽有,保证看懂,没有bug!交换节点版本!

    一.废话不多说,直接上代码.如果想看双向循环链表的朋友,可以在我的博客里找. 你好 #include <stdio.h> #include <stdlib.h>typedef ...

  2. 冒泡链表排序java_链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)...

    以下排序算法的正确性都可以在LeetCode的链表排序这一题检测.本文用到的链表结构如下(排序算法都是传入链表头指针作为参数,返回排序后的头指针) struct ListNode { int val; ...

  3. 链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)

    这篇文章分析一下链表的各种排序方法. 以下排序算法的正确性都可以在LeetCode的链表排序这一题检测.本文用到的链表结构如下(排序算法都是传入链表头指针作为参数,返回排序后的头指针) struct ...

  4. 单链表建立(头插法,头插法,用数组),求长,插入,删除,输出,释放(递归释放和循环释放),归并(递增和递减)

    学习地址:http://blog.csdn.net/stpeace/article/details/8091123 #include<iostream>using namespace st ...

  5. 链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定

    链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定 链表基本操作实现 c语言版本, 该程序在visual c++ 6.0上调试通过! 本人写该程序完全是为学习交流之用,还望大家多多 ...

  6. 排序算法 - 时间复杂度O(N*logN)的归并、快速排序算法

    目录 1.归并排序 2.快速排序 3.归并排序 VS 快速排序 归并排序.快速排序都使用了分治的思想,并且都基于递归进行实现,时间复杂度都是O(N*logN).分治是处理问题的一种思想,递归是一种编程 ...

  7. 单链表排序----快排 归并排序

    单链表排序----快排 & 归并排序 原文:http://blog.csdn.net/u012658346/article/details/51141288 题目描述:  给定一个乱序的单链表 ...

  8. 小白算法积累——单链表13#带头结点单链表+就地归并+改序

    题目:假设有两个按元素值递增次序排列的线性表,均以单链表的形式存储.请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表. 关键字:带头结点 ...

  9. 算法 合并有序序列(逆向双指针/穿线法/归并法)

    一.合并有序数组 1.1 题意 题目链接 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目. 请你 合 ...

最新文章

  1. CentOS6.2 KVM 虚拟机命令行安装配置
  2. Python知识点笔记-列表list、元组tuple和dict类型
  3. 一起来学习丨听海华大赛第一名团队聊比赛经验和心得
  4. scala的字符串的方法(五)
  5. visio 教程-绘图技巧、快捷键大全
  6. 指纹机和计算机无法连接,考勤机怎么连接到电脑?考勤机连接电脑之后操作指南!...
  7. mysql课程设计论文_课程设计项目源码,课程设计毕业设计项目,计算机毕业设计网 - 代码货栈...
  8. 学习linux方向,学习linux方向
  9. 8位计算机的八位代表什么,八位二进制是什么意思
  10. Netapp 两节点双活VS本地HA
  11. 第一台计算机英语怎么说,世界第一台计算机英文缩写名为
  12. PHP爆绝对路径方法总结帖
  13. 逃逸分析和标量替换技术,你明白了吗
  14. linux php-fpm 配置文件,linux下php-fpm开启与关闭方法
  15. Andorid-15k+的面试题。
  16. Redis入门完整教程:复制原理
  17. 基于YOLOv3的车辆号牌定位
  18. spring boot 配置默认数据连接池 HiKariCP
  19. jmeter中的响应断言
  20. 某高人整理的Java就业面试题大全【1】

热门文章

  1. CSS:过渡样式+鸭子表动画
  2. 如何看mysql版本_如何查看mysql版本的四种方法,MySQL版本查看
  3. 华为nova6se会搭载鸿蒙,华为nova6se支持无线充电吗 nova6全系标配40W超级快充
  4. php日历怎么存价格数据库,日历价格表?
  5. 亲人寄语贴上公交车(图)
  6. 初中孩子做作业能用计算机吗,作业帮,帮孩子还是害孩子?
  7. SU插件情报局 | SketchyFFD 形体变形工具详解(附插件获取)
  8. SuSE_Linux_Enterprise_11_SP3_x86_64下载地址
  9. 让人记忆深刻的2019春节营销案例
  10. Cannot GET /问题解决