Sort a linked list in O(n log n) time using constant space complexity.
这道题属于人生中第一次对链表进行操作,首先,不同于C++中的struct,java中可以用一个类来定义一个数据结构。
这道题一看没有任何思路,就看别人的代码,发现getmid是一个比较巧妙地得到链表中中间节点的方法,其次在主函数中用到了递归,这样每一次合并就相当于一个归并排序,二路归并。
最后在merge函数中,合并两个链表,比如说,递归的最里层,合并两个节点,很巧妙的将已经加入列表的列表的值设为Integer.MAX_VALUE;这样就可以将没有合并到有序列表中的另一个有序链表合并进去。
下面附上从网上找来的源码,继续学习啊,自己会的太少了
public static ListNode sortList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode p = getMid(head);
ListNode q;
q = p.next;
p.next = null;
p = head;
p = sortList(p);
q = sortList(q);
return merge(p, q);
}
public static ListNode getMid(ListNode head) {
ListNode p = head;
ListNode q = head;
while (p.next != null && q.next != null && q.next.next != null) {
p = p.next;
q = q.next.next;
}
return p;
}
public static ListNode merge(ListNode p, ListNode q) {
ListNode r = new ListNode(0);
ListNode res = r;
while (p != null || q != null) {
int a,b;
if (p == null)
a = Integer.MAX_VALUE;
else
a = p.val;
if (q == null)
b = Integer.MAX_VALUE;
else
b = q.val;
if (a < b) {
r.next = p;
p = p.next;
}
else {
r.next = q;
q = q.next;
}
r = r.next;
}
return res.next;
}
public static void main(String[] args){
ListNode[] ln = new ListNode[8];
ln[0] = new ListNode(2);
ln[1] = new ListNode(4);
ln[2] = new ListNode(5);
ln[3] = new ListNode(6);
ln[4] = new ListNode(3);
ln[5] = new ListNode(8);
ln[6] = new ListNode(10);
ln[7] = new ListNode(1);
ln[0].next = ln[1];
ln[1].next = ln[2];
ln[2].next = ln[3];
ln[3].next = ln[4];
ln[4].next = ln[5];
ln[5].next = ln[6];
ln[6].next = ln[7];
ln[7].next = null;
ListNode s = sortList(ln[0]);
while(s!=null){
System.out.println(s.val);
s= s.next;
}
}
原文:http://www.cnblogs.com/gracyandjohn/p/4418502.html