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; } }
时间: 2024-10-23 12:11:12