生活随笔
收集整理的這篇文章主要介紹了
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; |
| 05 | ????????ListNode slow = head; |
| 06 | ????????ListNode fast = head; |
| 08 | ????????while(fast.next !=?null?&& fast.next.next !=?null){ |
| 09 | ????????????slow = slow.next; |
| 10 | ????????????fast = fast.next.next; |
| 12 | ????????ListNode list2 = slow.next; |
| 13 | ????????slow.next =?null; |
| 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; |
| 24 | ????????last = newHead; |
| 25 | ????????//連接每個節點,只更換指針,因此空間復雜度為O(1) |
| 26 | ????????while(list1 !=?null?&& list2 !=?null){ |
| 27 | ????????????if(list1.val < list2.val){ |
| 28 | ????????????????last.next = list1; |
| 29 | ????????????????list1 = list1.next; |
| 31 | ????????????????last.next = list2; |
| 32 | ????????????????list2 = list2.next; |
| 34 | ????????????last = last.next; |
| 36 | ????????//最后剩余的部分,直接連接起來即可 |
| 37 | ????????if(list1 !=?null) last.next = list1; |
| 38 | ????????else?if(list2 !=?null) last.next = list2; |
| 39 | ????????return?newHead.next; |
| 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); |
| 56 | ????????l1 = sortList(l1); |
| 58 | ????????while(l1 !=?null){ |
| 59 | ????????????System.out.print(l1.val +?" "); |
| 60 | ????????????l1 = l1.next; |
2.快速排序實現
| 01 | //以end節點作為pivot進行劃分,返回劃分的節點的前一個節點 |
| 02 | public?static?ListNode partition(ListNode head, ListNode end){ |
| 03 | ????int?pivot = end.val; |
| 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; |
| 12 | ????????????tmpHead.val = tmp; |
| 14 | ????????tmpHead = tmpHead.next; |
| 16 | ????//有可能是劃分的節點就是第一個,此時返回null |
| 17 | ????if(lastSmallNode ==?null){ |
| 18 | ????????end.val = head.val; |
| 19 | ????????head.val = pivot; |
| 22 | ????????end.val = lastSmallNode.next.val; |
| 23 | ????????lastSmallNode.next.val = pivot; |
| 24 | ????????return?lastSmallNode; |
| 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); |
| 31 | ????quickSort(head, mid); |
| 34 | ????????quickSort(head.next, end); |
| 35 | ????//如果劃分點是最后一個位置,就無需再排序 |
| 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; |
| 42 | ????ListNode tail = head; |
| 43 | ????while(tail.next !=?null) |
| 44 | ????????tail = tail.next; |
| 45 | ????quickSort(head,tail); |
總結
以上是生活随笔為你收集整理的LeetCode-Sort List 链表排序的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。