1. 程式人生 > >Merge Sort Array and Merge Sort Linked List

Merge Sort Array and Merge Sort Linked List

Merge Sort Array: 看完stanford的 CS106B的video,https://www.youtube.com/watch?v=LlNawf0JeF0&list=PLnfg8b9vdpLn9exZweTJx44CII1bYczuk&index=55 醍醐灌頂;

public class Main {

  public static void mergeSort(int[] array) {
    if(array.length <=1){
      return;
    }

    int[] left = cutHalfArray(array, true);
    int[] right = cutHalfArray(array, false);

    mergeSort(left);
    mergeSort(right);

    //merge;
    int l1 = 0;
    int l2 = 0;
    for(int i=0; i<array.length; i++){
      // if right is over boundary, OR both of them have values, and left<right; pick up left value;
      if(l2>=right.length || (l1<left.length && left[l1] < right[l2])){
        array[i] = left[l1];
        l1++;
      } else {
        array[i] = right[l2];
        l2++;
      }
    }
  }

  public static  int[] cutHalfArray(int[] array, boolean isLeft) {
    int[] cutArray;
    if(isLeft) {
       cutArray= new int[array.length / 2];
      for(int i=0; i<array.length/2; i++){
        cutArray[i] = array[i];
      }
    } else {
      // 這個地方比較tricky,就是array,後半段有可能多點,例如:5個size,後半段是3.
      cutArray = new int[array.length - array.length/2]; 
      for(int i=array.length/2; i<array.length; i++){
        cutArray[i-array.length/2] = array[i];
      }
    }
    return cutArray;
  }

  private static void showArray (int[] array) {
    for(int i=0; i<array.length; i++) {
      System.out.print(array[i] + " ");
    }
  }

  public static void main(String[] args) {
    int[] array = {32, 2, 34, 5, 7, 9, 10, -1, 90, 100};
    mergeSort(array);
    showArray(array);

  }
}

Merge Sort LinkedList:

Sort a linked list in O(n log n) time using constant space complexity.

思路:merge sort 是nlogn

注意: 

1. 分開兩個list,找中點的時候,一般是找中點的前一個點,因為前面的list最後一個需要變成null,跟後面分開。

2. merge的時候,為了返回head node必須有個dump,hold住head,然後有個cur作為指標,連線下一個node。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    
    private ListNode findMiddelNode(ListNode node) {
        ListNode temp = new ListNode(0);
        temp.next = node;
        ListNode slow = temp;
        ListNode fast = temp;
        
        while(fast!=null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null) return head;
        // find middle point;
        ListNode slow = findMiddelNode(head);
        
        // split into two linkedlist;
        ListNode newhead = slow.next;
        slow.next = null;
        
        // sortList left;
        ListNode l1head = sortList(head);
        // sortList right;
        ListNode l2head = sortList(newhead);
        
        // merge and return;
        ListNode l1cur = l1head;
        ListNode l2cur = l2head;
        ListNode temp = new ListNode(0);
        ListNode cur = temp;
        while(l1cur!=null && l2cur!=null) {
            if(l1cur.val < l2cur.val) {
                cur.next = l1cur;
                l1cur = l1cur.next;
                cur = cur.next;
            } else {
                cur.next = l2cur;
                l2cur = l2cur.next;
                cur = cur.next;
            }
        }
        if(l1cur!=null) {
            cur.next = l1cur;
        }
        if(l2cur!=null) {
            cur.next = l2cur;
        }
        return temp.next;
    }
}

3. 這題再聯想到:如何用 insertion sort 去sort integer array和 linked list