题目:对单链表进行排序,要求不改变每个节点内的值。

1.首先自然而然地会想到快速排序,毕竟是一个经典的排序算法。但是在排序过程中要求不能改变节点中的值,就必须通过改变节点中的指针来交换节点。而且快速排序的时间复杂度的下限是O(N^2),当链表接近有序时,可能还没有插入排序来的快。

直接上代码(代码是康神 撸的,我太菜撸不出来

//List Quick Sort
class Solution {
public:ListNode* sortList(ListNode* head) {if (head == NULL) return head;ListNode dummy(-1);dummy.next = head;quicksort(&dummy, NULL);return dummy.next;}
private:void quicksort(ListNode* pre, ListNode* end) {if ( pre->next == end|| pre->next->next == end)return;ListNode* pivotpos = partition(pre, end);quicksort(pre, pivotpos);quicksort(pivotpos, end);}ListNode* partition(ListNode* pre, ListNode* end){ListNode* prehead = pre;ListNode* head = pre->next;ListNode* prepivotpos = pre;ListNode* pivotpos = pre->next;ListNode* swapnode = pivotpos->next;ListNode* preswap = pivotpos;int pivot = pivotpos->val;while (swapnode != end){if (swapnode->val < pivot){prepivotpos = pivotpos;pivotpos = pivotpos->next;if (pivotpos != swapnode)swapLink(prepivotpos, pivotpos, preswap, swapnode);}preswap = swapnode;swapnode = swapnode->next;}swapLink(prehead, head, prepivotpos, pivotpos);return pivotpos;}void swapLink(ListNode* &prepivotpos, ListNode* &pivotpos, ListNode* &preswap, ListNode* &swapnode){if (pivotpos->next == swapnode){ListNode* end = swapnode->next;prepivotpos->next = swapnode;swapnode->next = pivotpos;pivotpos->next = end;}else{ListNode* endpivot = pivotpos->next;ListNode* endswap = swapnode->next;prepivotpos->next = swapnode;swapnode->next = endpivot;preswap->next = pivotpos;pivotpos->next = endswap;}swap(pivotpos, swapnode);}
};

2.其实这是leetcode上的原题,但是原题并没有规定不能改变节点中的值。上述代码在leetcode中运行超时,主要原因在于,当测试用例中包含大量重复值的时候,快排性能迅速下降,所以改用三路快排的方法,以pivot为基准值把原链表分成小于、等于、大于pivot的三条链表,分别递归排序后再串联。

//List three-way Quick Sort
class Solution {
public:ListNode* sortList(ListNode* head) {if (NULL == head || NULL == head->next) return head;int pivot = head->val;ListNode less(-1), equal(-1), greater(-1);ListNode *lt = &less, *eq = &equal, *gt = &greater;while (head != NULL) {if (head->val < pivot) {lt->next = head;lt = lt->next;head = head->next;lt->next = NULL;}else if (head->val > pivot) {gt->next = head;gt = gt->next;head = head->next;gt->next = NULL;}else {eq->next = head;eq = eq->next;head = head->next;eq->next = NULL;}}ListNode* left = sortList(less.next);ListNode* right = sortList(greater.next);if (NULL == left) {left = equal.next;}else {lt = &less;while (lt->next != NULL) lt = lt->next;lt->next = equal.next;}eq = &equal;while (eq->next != NULL) eq = eq->next;eq->next = right;return left;}
};

3.链表排序也适合用归并排序,且时间复杂度的下限是O(NlogN),只是在遍历寻找链表的中间节点的时候比较费时,处理大量数据的时候尤其突出。

//List Merge Sort
class Solution {
public:ListNode* sortList(ListNode* head) {if (!head || !head->next) return head;ListNode *fast = head, *slow = head;while (fast->next&&fast->next->next){fast = fast->next->next;slow = slow->next;}fast = slow->next;slow->next = NULL;ListNode *l1 = sortList(head);ListNode *l2 = sortList(fast);return mergeTwoLists(l1, l2);}
private:ListNode* mergeTwoLists(ListNode* lhs, ListNode* rhs) {ListNode dummy(-1);ListNode *cur = &dummy;while (lhs&&rhs)if (lhs->val < rhs->val){cur->next = lhs;cur = lhs;lhs = lhs->next;}else{cur->next = rhs;cur = rhs;rhs = rhs->next;}if (lhs)cur->next = lhs;if (rhs)cur->next = rhs;return dummy.next;}
};

关于三路快排与双基准排序,准备有时间了再写一个总结。

http://www.cnblogs.com/chenying99/archive/2014/07/10/3836816.html

【阿里面试】链表排序总结相关推荐

  1. 我是如何通过阿里面试的?

    笔者参加18年阿里春招,有幸最终拿到阿里offer,base杭州,岗位客户端开发.一直忙于其他事情,拿到意向已经过去十多天,在此分享一些关于面试的干货,攒一波RP,回馈社会. 从阿里面试说起,阿里的面 ...

  2. 是如何通过阿里面试的?

    从阿里面试说起,阿里的面试一般采用电话面试的形式.笔者一共参加五轮面试,一面电话面试+在线编程,二面视频面试+在线编程,三面部门boss面试,四面交叉面,五面HR.在此分享五轮面试的大概问题吧,笔者是 ...

  3. 美团面试,360面试 ,滴滴面试,阿里面试,百度面试,京东面试,搜狗面试:

    一.基础知识:   1.CurrentHashMap的数据结构,Java1.8 与 java 1.7的区别,增加了那些特性 这个其实是考了一下编程思路,hashMap(链表+数组)==>1.8之 ...

  4. mysql字符凭藉_凭借清华扫地僧的路线指引,从Java基础到算法,吊打阿里面试官!...

    本文素材来自于一位铁粉经验分享 上周收到字节跳动的面试邀请,真的又惊又喜.惊得是害怕面试时会被秒杀:喜得是有大厂邀请,是自己能力的一种体现.于是抱着试试看的轻松心态,居然一不小心就反杀了面试官(嘻嘻, ...

  5. 最强阿里面试126题:数据结构+并发编程+Redis+设计模式+微服务

    BAT技术面试范围 数据结构与算法:最常见的各种排序,最好能手写 Java高级:JVM内存结构.垃圾回收器.回收算法.GC.并发编程相关(多线程.线程池等).NIO/BIO.各种集合类的比较优劣势(底 ...

  6. 奇数位升序偶数位降序链表排序

    题目描述:一个链表,奇数位升序偶数位降序,让链表变成升序的. 比如:1 8 3 6 5 4 7 2 9,最后输出1 2 3 4 5 6 7 8 9. 分析: 这道题可以分成三步: 首先根据奇数位和偶数 ...

  7. 阿里面试官:“你有高并发经验吗?”

    "高并发经验你有吗?" 阿里面试官一句话问倒了我. 实际上,不在BAT这样的大厂工作,是很难接触到千万级别的高并发的. 但也正是这种难得,让各个大厂都抢着要这样的人才! 下面这六道 ...

  8. 阿里面试必过的 Java 面试参考指南全集

    又到了金三银四找工作的季节,小鱼熬了一晚上为大家展现一篇大厂及阿里面试完整题及详解答.正在为面试发愁的朋友赶紧看过来啦. 大提纲: 1.分布式 一.大型网站系统的特点 高并发,大流l量 高可用 海量数 ...

  9. 刚参加完阿里面试:一面+二面+三面+HR四面,我的复盘经验总结!

    阿里中间件团队一面: 第一步先自我介绍? 介绍自己的项目经验和个人的擅长点,面试官主要考察你的表达能力和语言精简能力. 第二步:项目中做了什么,难点在哪里? 主要是想了解参与过技术难度最大的项目难点, ...

最新文章

  1. 设计模式学习笔记十五——Command模式
  2. MFC界面库BCGControlBar v25.0新功能详解六:属性网格和其他
  3. 【CF】556D A Lot of Games
  4. Bag of Tricks for Efficient Text Classification(Fasttext)
  5. mybatis中getMapper是怎么通过动态代理得到dao接口的实现类并执行mapper文件sql语句的
  6. 大话数据结构22:几种常见的静态查找算法
  7. 邻接矩阵和邻接表_[力扣743] 带权邻接表的单源最短路
  8. 简析Kubernetes八大重要特性
  9. MTK PerfService介绍
  10. 分布式任务调度平台XXL-JOB一
  11. 大华服务器装系统,clonezilla安装系统理论篇
  12. Netty 如何做到单机百万并发?
  13. C语言中extern的用法
  14. docker限制cpu、内存使用
  15. 软件设计(中线提取)
  16. 大陆资金港股打新股亲身体验全流程
  17. win7插了耳机还是外放_安卓手机用耳机听歌音量太大怎么办
  18. ★ 太空飞行计划 最大权闭合图+输出方案
  19. 电脑开机时出现error:unknown filesystem
  20. 驾照考试科目三灯光测试

热门文章

  1. Redis数据结构-SkipList(跳表)
  2. 画饼画到世界地图上:按比例呈现多组数据
  3. 计算机信息管理专业自考教材,计算机信息管理自考本科课程
  4. java 水印排版_java图片加水印代码 最好有实例!!!先谢了!!
  5. 一看就会(废)的最小二乘法推导
  6. 经济学人万字总结17年AI领域并购趋势:谷歌领跑,人才竞争白热化
  7. 82.Hive SQL插入动态分区的异常分析
  8. 在字符串中查找一个字符
  9. android系统底层的updater 命令,Android ROM 刷机脚本 updater-script 的基本流程和初级语句...
  10. 用win系统PC或笔记本作为Mac的扩展屏