生活随笔
收集整理的这篇文章主要介绍了
LeetCode-Sort List 链表排序
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
原题链接: http://oj.leetcode.com/problems/sort-list/
对链表进行排序,要求的时间复杂度为O(n log n)。nlogn的排序有快速排序、归并排序、堆排序。双向链表用快排比较适合,堆排序也可以用于链表,单向链表适合用归并排序。题目要求的是常数的空间复杂度,因为这里用了递归,如果算上栈空间的话,也要 o(logn)的复杂度。
关于链表的划分,这里使用了快慢指针,从中间节点进行切开成单独的链表。在merge之后又会合并成一个链表。
以下分别用归并排序和快速排序实现(Java),遗憾的是快速排序的实现超时了,毕竟交换数据的次数过多,没有归并排序之家更换指针要快。快速排序的实现大家可以忽略,代码写的不太好。
关于链表的归并排序可参考之前的一篇文章归并排序对链表进行排序
,只是实现比下面这个有些复杂。
1. 归并排序实现
| 01 | public class MergetSortList { |
| 03 | public static ListNode sortList(ListNode head) { |
| 04 | if(head == null || head.next == null) return head; |
| 08 | while(fast.next != null && fast.next.next != null){ |
| 10 | fast = fast.next.next; |
| 12 | ListNode list2 = slow.next; |
| 14 | head = sortList(head); |
| 15 | list2 = sortList(list2); |
| 16 | return merge(head, list2); |
| 19 | private static ListNode merge(ListNode list1, ListNode list2) { |
| 20 | if(list1 == null) return list2; |
| 21 | if(list2 == null) return list1; |
| 22 | ListNode newHead = new ListNode(0);//链表头不存储实际数据 |
| 23 | ListNode last = newHead; |
| 25 | //连接每个节点,只更换指针,因此空间复杂度为O(1) |
| 26 | while(list1 != null && list2 != null){ |
| 27 | if(list1.val < list2.val){ |
| 37 | if(list1 != null) last.next = list1; |
| 38 | else if(list2 != null) last.next = list2; |
| 42 | public static void main(String[] args) { |
| 43 | ListNode l1 = new ListNode(8); |
| 44 | ListNode l2 = new ListNode(7); |
| 45 | ListNode l3 = new ListNode(6); |
| 46 | ListNode l4 = new ListNode(5); |
| 47 | ListNode l5 = new ListNode(4); |
| 48 | ListNode l6 = new ListNode(3); |
| 59 | System.out.print(l1.val + " "); |
2.快速排序实现
| 01 | //以end节点作为pivot进行划分,返回划分的节点的前一个节点 |
| 02 | public static ListNode partition(ListNode head, ListNode end){ |
| 04 | ListNode lastSmallNode = null; |
| 05 | ListNode tmpHead = head; |
| 06 | while(tmpHead != end){ |
| 07 | if(tmpHead.val < pivot){ |
| 08 | if(lastSmallNode == null) lastSmallNode = head; |
| 09 | else lastSmallNode = lastSmallNode.next; |
| 10 | int tmp = lastSmallNode.val; |
| 11 | lastSmallNode.val = tmpHead.val; |
| 14 | tmpHead = tmpHead.next; |
| 16 | //有可能是划分的节点就是第一个,此时返回null |
| 17 | if(lastSmallNode == null){ |
| 22 | end.val = lastSmallNode.next.val; |
| 23 | lastSmallNode.next.val = pivot; |
| 28 | public static void quickSort(ListNode head, ListNode end){ |
| 29 | if( head == null || head == end || end == null || head.next == null) return; |
| 30 | ListNode mid = partition(head, end); |
| 34 | quickSort(head.next, end); |
| 36 | else if(mid != end && mid.next != null && mid.next != end) |
| 37 | quickSort(mid.next.next, end); |
| 40 | public static ListNode sortList(ListNode head) { |
| 41 | if(head == null || head.next == null) return head; |
| 43 | while(tail.next != null) |
总结
以上是生活随笔为你收集整理的LeetCode-Sort List 链表排序的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。