1、归并排序:
将链表拆分成两个链表,递归,归并,将两个已排序链表合并
public ListNode sortList(ListNode head) {
// write your code here
if (head == null || head.next == null) return head;
ListNode slow = head, fast = head, pre = head;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
pre.next = null;
return merge(sortList(head), sortList(slow));
}
public ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if (l1 != null) cur.next = l1;
if (l2 != null) cur.next = l2;
return dummy.next;
}
2、快速排序
根据普通快排的思路,选择1个点为中心点,保证中心点左边比中心点小,中心点右边比中心点大即可.
单链表的实现为:
1.使第一个节点为中心点.
2.创建2个指针(p,q),p指向头结点,q指向p的下一个节点.
3.q开始遍历,如果发现q的值比中心点的值小,则此时p=p->next,并且执行当前p的值和q的值交换,q遍历到链表尾即可.
4.把头结点的值和p的值执行交换.此时p节点为中心点,并且完成1轮快排
5.使用递归的方法即可完成排序
public ListNode sortList(ListNode head) {
// write your code here
if(head == null || head.next == null)
return head;
ListNode end = head;
while(end.next != null){
end = end.next;
}
quickSort(head, end);
return head;
}
public void quickSort(ListNode begin, ListNode end) {
//判断为空,判断是不是只有一个节点
if (begin == null || end == null || begin == end)
return;
//从第一个节点和第一个节点的后面一个几点
ListNode first = begin;
ListNode second = begin.next;
int nMidValue = begin.val;
//结束条件,second到最后了
while (second != end.next && second != null) {
if (second.val < nMidValue) {
first = first.next;
//判断一下,避免后面的数比第一个数小,不用换的局面
if (first != second) {
int temp = first.val;
first.val = second.val;
second.val = temp;
}
}
second = second.next;
}
//判断,有些情况是不用换的,提升性能
if (begin != first) {
int temp = begin.val;
begin.val = first.val;
first.val = temp;
}
//前部分递归
quickSort(begin, first);
//后部分递归
quickSort(first.next, end);
}