【LeetCode热题100】--148.排序链表

148.排序链表

【LeetCode热题100】--148.排序链表_第1张图片

对链表进行排序最适合的算法就是归并排序:
对链表自顶向下归并排序的过程:

  • 找到链表的中点,以中点为分界,将链表拆分成两个子链表,寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2步,慢指针每次移动 1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点
  • 对两个子链表分别排序
  • 将两个排序后的子链表合并,得到完整的排序后的链表

上述过程可以通过递归实现。递归的终止条件是链表的节点个数小于或等于 1,即当链表为空或者链表只包含 1个节点时,不需要对链表进行拆分和排序。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        return sortList(head,null);
    }    
    public ListNode sortList(ListNode head,ListNode tail){
        if(head == null){
            return head;
        }
        if(head.next == tail){
            head.next = null;
            return head;
        }
        ListNode slow = head,fast = head;
        while(fast != tail){
            slow = slow.next;
            fast = fast.next;
            if(fast!=tail){
                fast = fast.next;
            }
        }
        ListNode mid = slow;
        ListNode list1 = sortList(head,mid);
        ListNode list2= sortList(mid,tail);
        ListNode sorted = merge(list1,list2);
        return sorted;

    }
    public ListNode merge(ListNode head1,ListNode head2){  //合并两个有序链表
        ListNode dummy = new ListNode(0);
        ListNode temp = dummy,temp1 = head1,temp2 = head2;
        while(temp1 !=null &&temp2 !=null){
            if(temp1.val <= temp2.val){
                temp.next = temp1;
                temp1 = temp1.next;
            }else{
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        if(temp1!=null){
            temp.next = temp1;
        }else if(temp2!=null){
            temp.next = temp2;
        }
        return dummy.next;

    }
}

你可能感兴趣的:(LeetCode,leetcode,链表,算法)