rt, 最近的面试题,面的时候敲的血崩,特此写下博客以作留念
如有错误,欢迎指正
class Node{
int val;
Node next;
}
import java.util.Random;
class Node {
public int val;
public Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
public class Test {
public static void main(String[] args) {
Random random = new Random(47);
Node head = new Node(10);
Node p = head;
for(int i = 0; i < 9; ++i) {
p.next = new Node(random.nextInt(20));
p = p.next;
}
System.out.print("归并前:");
for (Node i = head; i != null; i = i.next)
System.out.print(i.val + " ");
System.out.println();
head = MergeSort(head, 10);
System.out.print("归并后:");
for (Node i = head; i != null; i = i.next)
System.out.print(i.val + " ");
System.out.println();
}
//传入链表头和链表长度,返回新链表头,对以head开始的长度为len的链表排序
private static Node MergeSort(Node head, int len) {
if (len > 1) {
int m = len / 2;
head = MergeSort(head, m);
Node p = head;
for (int i = 0; i < m - 1; ++i)
p = p.next;
p.next = MergeSort(p.next, len - m);
head = merge(head, len, m);
}
return head;
}
//对以head开始的长度为len的链表合并, [1, m]和[m+1, len]的两条链表
private static Node merge(Node head, int len, int m) {
Node p1 = head;
Node p1Pre = null;
Node p2 = head.next;
Node p2Pre = head;
for (int i = 0; i < m - 1; ++i) {
p2 = p2.next;
p2Pre = p2Pre.next;
}
int l = 1;
int r = m + 1;
while (l <= m && r <= len) { //将链表归并到p1链上
if (p1.val <= p2.val) {
p1Pre = p1;
p1 = p1.next;
++l;
} else { //将p2指向的节点移到p1的前面
p2Pre.next = p2.next;
p2.next = p1;
if (p1Pre == null) {
head = p2;
p1Pre = head;
} else {
p1Pre.next = p2;
p1Pre = p2;
}
p2 = p2Pre.next;
++r;
}
}
return head;
}
}
虽然链表的归并无需辅存,但链表的查找增加了时间复杂度,而且写的时候容易出错,链表的归并也并不好用