148.Sort List---链表排序(冒泡、归并)

题目链接

题目大意:对链表进行排序,要求时间复杂度是o(nlgn)。

法一:冒泡,不交换结点,而交换结点中的数值。超时了。代码如下:

 1     public ListNode sortList(ListNode head) {
 2         if(head == null || head.next == null) {
 3             return head;
 4         }
 5         ListNode cur = null, tail = null;
 6         cur = head;
 7         while(cur.next != tail) {
 8             while(cur.next != tail) {
 9                 //其实这里交换的是两个相邻结点的值,并没有交换两个结点指针
10                 if(cur.val > cur.next.val) {
11                     int tmp = cur.val;
12                     cur.val = cur.next.val;
13                     cur.next.val = tmp;
14                 }
15                 cur = cur.next;
16             }
17             //每一趟排序都会把一个相对最大的数排到最后一个,所以这里要将tail置为cur,而不是一直是null
18             tail = cur;//下一次遍历的尾结点是当前结点
19             //每一趟都再次从头开始遍历
20             cur = head;//遍历起始结点重置为头结点
21         }
22         return head;
23     }
View Code

法二:归并,交换结点,利用尾插,谁小谁放在前面。代码如下(耗时7ms):

 1     public ListNode sortList(ListNode head) {
 2         if(head == null || head.next == null) {
 3             return head;
 4         }
 5         //划分成两个链表,由快慢指针得到。
 6         //最终slow会指向第二个链表的起始位置,fast会指向第二个链表的末尾,pre会指向第一个链表的末尾
 7         ListNode pre = null, slow = head, fast = head;
 8         while(fast != null && fast.next != null) {
 9             pre = slow;
10             slow = slow.next;
11             fast = fast.next.next;
12         }
13         //第一个链表的终结
14         pre.next = null;
15         //分别对两个链表进行排序
16         //head是第一个链表的头,slow是第二个链表的头
17         ListNode l1 = sortList(head);
18         ListNode l2 = sortList(slow);
19         //归并l1和l2
20         return merge(l1, l2);
21     }
22     private static ListNode merge(ListNode l1, ListNode l2) {
23         //l头节点初始化为0,返回的时候返回l.next即可,即不带头结点的指针
24         ListNode l = new ListNode(0), p = l;
25         while(l1 != null && l2 != null) {
26             //尾插
27             if(l1.val < l2.val) {
28                 p.next = l1;
29                 l1 = l1.next;
30             }
31             else {
32                 p.next = l2;
33                 l2 = l2.next;
34             }
35             p = p.next;
36         }
37         //如果还有结点,则直接放在其后即可
38         if(l1 != null) {
39             p.next = l1;
40         }
41         if(l2 != null) {
42             p.next = l2;
43         }
44         return l.next;
45     }
View Code
原文地址:https://www.cnblogs.com/cing/p/8691949.html