归并排序

归并排序(Merge Sort)是John von Neumann与1945年创造的,它是性能最好的排序算法之一,但是他的时间复杂度为 O(n log n)

归并排序的主要思想是将大问题归类成若干个更小的问题来替代,解决小问题后将这些内容合并

我们把归并的思想用到数组的排序中,我们先将一个有 n 个元素的数组归类成若干小数组,然后分别排序后合并

比如我们要将[2, 1, 5, 4, 9]这个数组排序

首先我们要将这个数组归类成小数组,比如先分成两个 [2, 1,][5, 4, 9] ,这样的话就成了左边的数组和右边的数组,然后我们利用递归的思想,再将这些小数组进行拆分,直到最后拆分成只有一个元素的数组, [2][1][5][4][9]

然后我们要将归类拆分的数组合并,在合并的同时我们要进行相应的排序,这其实就是刚才说的归并思想,我们将一个大问题拆分成若干小问题依次来解决

第一轮合并我们会得到 [1, 2][4, 5] 以及 [9] 三个数组,我们继续排序并合并,会合并成 [1, 2][4, 5, 9] 两个数组, 依次递归以后会合并成一个完整的排序好的数组, [1, 2, 4, 5, 9]

代码如下


func mergeSort<T: Comparable>(array: [T]) -> [T] {
    guard array.count > 1 else {
        return array
    }
    let ave = array.count / 2
    let left = mergeSort(array: Array(array[0..<ave]))
    let right =  mergeSort(array: Array(array[ave..<array.count]))
    return merge(left: left, right: right)
}


func merge<T: Comparable>(left: [T] , right: [T]) -> [T] {
    var lIndex = 0
    var rIndex = 0
    var mArray = [T]()
    
    while lIndex < left.count && rIndex < right.count {
        if left[lIndex] > right[rIndex] {
            mArray.append(right[rIndex])
            rIndex += 1
        } else if left[lIndex] < right[rIndex] {
            mArray.append(left[lIndex])
            lIndex += 1
        } else {
            mArray.append(left[lIndex])
            lIndex += 1
            mArray.append(right[rIndex])
            rIndex += 1
        }
    }

    while lIndex < left.count {
        mArray.append(left[lIndex])
        lIndex += 1
    }

    while rIndex < right.count {
        mArray.append(right[rIndex])
        rIndex += 1
    }
    return mArray
}