排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

按照题目要求,在O(n log n)时间复杂度下,首先想到七大排序中的归并排序,因为快排的需要双指针,指向首尾,单链表后一个元素没有前一个元素指针。
思路:和归并排序思路一样,归并思想不在此叙述,下面附上归并排序链接:https://www.cnblogs.com/du001011/p/10520272.html
代码如下:
    
  

    /*

      1.归并排序思想
      2.找到中间节点
      3.进行归并排序

    */

   public static ListNode sortList(ListNode head) {
        return head == null ? head:mergeSort(head);
    }
    //归并
    private static ListNode mergeSort(ListNode head) {
        if (head.next == null) {
            return head;
        }
      //快慢指针找出中间结点,这块需要注意一点就是
      //我们需要一个标记sign跟踪慢结点,当找出中间结点时,
      //让中间结点前一结点即sign的下一个结点指向空
      //这样做的目的是为了使前半部分链表和后半部分链表进行合并排序
      

      //慢结点 ListNode s
= head;
      //快结点 ListNode f
= head;
      //标记结点 ListNode sign
= null; while (f.next != null) { sign = s; s = s.next; f = f.next.next; }
      //标记结点下一个结点为空 sign.next
= null; ListNode left = mergeSort(head); ListNode right = mergeSort(s); return merge(left, right); } //合并两个链表 public static ListNode merge(ListNode l, ListNode r) { ListNode dummyHead = new ListNode(0); ListNode cur = dummyHead; while (l != null && r != null) { if (l.val <= r.val) { cur.next = l; cur = cur.next; l = l.next; } else { cur.next = r; cur = cur.next; r = r.next; } } if (l != null) { cur.next = l; } if (r != null) { cur.next = r; } return dummyHead.next; }

 

 
posted @ 2019-03-27 20:35  码到成功hy  阅读(5372)  评论(0编辑  收藏  举报
获取

hahah

name age option