這題就是merge sort的鏈表實(shí)現(xiàn)硝全。
先看一下mergeSort:
public class myMergeSort {
static int number = 0;
public static void main(String[] args) {
int[] a = {26, 5, 98, 108, 28, 99, 100, 56, 34, 1, 45, 69};
printArray("排序前:", a);
MergeSort(a);
printArray("排序后:", a);
}
private static void printArray(String pre, int[] a) {
System.out.print(pre + "\n");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + "\t");
System.out.println();
}
private static void MergeSort(int[] a) {
// TODO Auto-generated method stub
System.out.println("開(kāi)始排序");
Sort(a, 0, a.length - 1);
}
private static void Sort(int[] a, int left, int right) {
if (left >= right)
return;
int mid = (left + right) / 2;
//二路歸并排序里面有兩個(gè)Sort,多路歸并排序里面寫(xiě)多個(gè)Sort就可以了
Sort(a, left, mid);
Sort(a, mid + 1, right);
merge(a, left, mid, right);
}
private static void merge(int[] a, int left, int mid, int right) {
int[] tmp = new int[a.length];
int r1 = mid + 1;
int tIndex = left;
int cIndex = left;
// 逐個(gè)歸并
while (left <= mid && r1 <= right) {
if (a[left] <= a[r1])
tmp[tIndex++] = a[left++];
else
tmp[tIndex++] = a[r1++];
}
// 將左邊剩余的歸并
while (left <= mid) {
tmp[tIndex++] = a[left++];
}
// 將右邊剩余的歸并
while (r1 <= right) {
tmp[tIndex++] = a[r1++];
}
System.out.println("第" + (++number) + "趟排序:\t");
// TODO Auto-generated method stub
//從臨時(shí)數(shù)組拷貝到原數(shù)組
while (cIndex <= right) {
a[cIndex] = tmp[cIndex];
//輸出中間歸并排序結(jié)果
System.out.print(a[cIndex] + "\t");
cIndex++;
}
System.out.println();
}
}
復(fù)雜度O(nlogn)赡艰。
這題的解法我看了https://leetcode.com/problems/sort-list/#/solutions
前半部分divide的遞歸部分比較難,后半部分就是merge two sorted lists斤葱。
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode prev = new ListNode(-1);
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
//prev把slow前面那個(gè)node跟slow之間的link斷開(kāi)
prev.next = null;
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
return merge(l1, l2);
}
private ListNode merge(ListNode l1, ListNode l2) {
ListNode node = new ListNode(-1);
ListNode l = node;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
l.next = l1;
l1 = l1.next;
} else {
l.next = l2;
l2 = l2.next;
}
l = l.next;
}
if (l1 != null) {
l.next = l1;
}
if (l2 != null) {
l.next = l2;
}
return node.next;
}