题目描述 : 给定一个无序单链表,实现单链表的排序(按升序排序)。
输入 [1,3,2,4,5]
返回值 {1,2,3,4,5}
归并排序(就跟模板一样):
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
public ListNode sortInList(ListNode head) {
if(null ==head|| head.next == null)return head;
return mergesort(head);
}
public ListNode mergesort(ListNode head){
if(null==head || head.next == null) return head;
ListNode mid = findmid(head);
ListNode l1 = mergesort(head);
ListNode l2 = mergesort(mid);
return merge(l1, l2);
}
public ListNode findmid(ListNode head){
if(null==head || head.next == null) return head;
ListNode fast = head.next, slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
ListNode ret = slow.next;
slow.next = null;
return ret;
}
public ListNode merge(ListNode l1, ListNode l2){
ListNode dummy = new ListNode(-1);
ListNode ret = dummy;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
dummy.next = l1;
dummy = dummy.next;
l1 = l1.next;
}else{
dummy.next = l2;
dummy = dummy.next;
l2 = l2.next;
}
}
dummy.next = l1==null ? l2 : l1;
return ret.next;
}
}
我又要说好玩的事情了:
看下面的merge函数:
public static ListNode merge(ListNode l1, ListNode l2){
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val < l2.val){
l1.next = merge(l1.next, l2);
return l1;
}else{
l2.next = merge(l1, l2.next);
return l2;
}
}
在LEETCode上提交是能够通过的,在牛客上就不行:
为什么锤子会出现这种结果呢,谁知道麻烦@我一下,谢谢啦。
快速排序:
这里的partition(ListNode head, ListNode end)函数,用了双指针策略:不是left和right的那种双指针,是p1和p2,p1之前的是小于头结点的,p1之后是大于头结点的,p2是用来遍历的…
借鉴了这里的图和话
需要两个指针p1和p2,但是不同的是,这两个指针都是从前往后移动,移动的过程中保持p1之前的key都小于选定的key,p1和p2之间的key都大于选定的key,这样当p2走到末尾时交换p1与key值便完成了一次快排
public ListNode sortList(ListNode head) {
if(head== null || head.next == null)return head;
quicksort(head, null);
return head;
}
public void quicksort(ListNode head, ListNode end){
if(head == end) return;
ListNode node = partition(head, end);
quicksort(head, node);
quicksort(node.next, end);
}
public ListNode partition(ListNode head, ListNode end){
ListNode p1 = head, p2 = head.next;
while(p2 != end){
if(p2.val < head.val){
p1 = p1.next;
int tem = p1.val;
p1.val = p2.val;
p2.val = tem;
}
p2 = p2.next;
}
if(p1 != head){
int tem = p1.val;
p1.val = head.val;
head.val = tem;
}
return p1;
}