package _Sort.Algorithm /** * https://www.geeksforgeeks.org/merge-sort/ * https://www.cnblogs.com/chengxiao/p/6194356.html * best/worst/average Time complexity are O(nlogn), Space complexity is O(n), stable * # is Divide and Conquer algorithm * Basic idea * 1. find the middle point to divide the array into two halves; * 2. Call MergeSort for first halves; * 3. Call MergeSort for second halves; * 4. Merge two halves; * */ class MergeSort { fun sortArray(array: IntArray): IntArray { //create temp array first, avoid create temp in recursion val tempArray = IntArray(array.size) val left = 0 val right = array.size - 1 sort(array, left, right, tempArray) //printArray(array) return array } private fun printArray(array: IntArray) { for (item in array) { print("$item,") } } private fun sort(array: IntArray, left: Int, right: Int, tempArray: IntArray) { if (left < right) { val mid = (left + right) / 2 sort(array, left, mid, tempArray) sort(array, mid + 1, right, tempArray) merge(array, left, mid, right, tempArray) } } private fun merge(array: IntArray, left: Int, mid: Int, right: Int, tempArray: IntArray) { var i = left var j = mid + 1 var k = 0 //merge the sub arrays while (i <= mid && j <= right) { if (array[i] <= array[j]) { tempArray[k] = array[i] i++ } else { tempArray[k] = array[j] j++ } k++ } //add remaining elements of L[] while (i <= mid) { tempArray[k] = array[i] i++ k++ } //add remaining elements of R[] while (j <= right) { tempArray[k] = array[j] j++ k++ } //copy temp into original k=0 for (i in left until right+1) { array[i] = tempArray[k++] } } }