Swift 3.0實現面試常考的排序算法

1.插入排序

⒈ 從第一個元素開始,該元素可以認為已經被排序
⒉ 取出下一個元素,在已經排序的元素序列中從后向前掃描
⒊ 如果該元素(已排序)大于新元素,將該元素移到下一位置
⒋ 重復步驟3,直到找到已排序的元素小于或者等于新元素的位置
⒌ 將新元素插入到下一位置中
⒍ 重復步驟2~5

  public func insertionSort(arr: inout Array<Int>) {//時間復雜度O(n^2)
    for i in 0..<arr.count - 1 {
        if arr[i + 1] < arr[i] {
            let temp = arr[i + 1]
            for j in (1...(i + 1)).reversed() {
                if arr[j - 1] > temp {
                    (arr[j - 1],arr[j]) = (arr[j],arr[j - 1])
                }
            }
        }
    }
}

2.冒泡排序

⒈比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
⒉ 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
⒊ 針對所有的元素重復以上的步驟,除了最后一個。
⒋ 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。

  public func bubbleSort(arr: inout Array<Int>) {//時間復雜度O(n^2)
    for i in 0..<(arr.count - 1) {
        for j in 0..<(arr.count - i - 1) {
            if arr[j] > arr[j + 1] {
                (arr[j],arr[j + 1]) = (arr[j + 1],arr[j])
            }
        }
    }
}

3.快速排序(冒泡排序的改進版)

⒈設置兩個變量i、j,排序開始的時候:i=0,j=n-1。
⒉ 以第一個數組元素作為關鍵數據,賦值給key,即key=A[0]。
⒊ 從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小于key的值A[j],將A[j]和A[i]互換。
⒋ 從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大于key的A[i],將A[i]和A[j]互換。
⒌重復第3、4步,直到i=j

 public func quickSort(arr: inout Array<Int>, leftIndex:  Int, rightIndex:  Int) {
    if leftIndex < rightIndex {
        var left = leftIndex
        var right = rightIndex
        let midIndex = getMidIndex(arr: &mArray, leftIndex: &left, rightIndex: &right)
        quickSort(arr: &mArray, leftIndex: leftIndex, rightIndex: midIndex - 1)
        quickSort(arr: &mArray, leftIndex: midIndex + 1, rightIndex: rightIndex)
    }
}

private func getMidIndex(arr: inout Array<Int>, leftIndex: inout Int, rightIndex: inout Int) -> (Int) {
    let temp = arr[leftIndex]
    while leftIndex < rightIndex {

        while leftIndex < rightIndex && temp <= arr[rightIndex] {
            rightIndex -= 1
        }
        if leftIndex < rightIndex {
            arr[leftIndex] = arr[rightIndex]
        }
        while leftIndex < rightIndex && arr[leftIndex] <= temp {
            leftIndex += 1
        }
        if leftIndex < rightIndex {
            arr[rightIndex] = arr[leftIndex]
        }
    }
    arr[leftIndex] = temp
    return leftIndex
}

4.歸并排序(速度僅次于快速排序)

⒈將序列每相鄰兩個數字進行歸并操作(merge),形成floor(n/2)個序列,排序后每個序列包含兩個元素。
⒉ 將上述序列再次歸并,形成floor(n/4)個序列,每個序列包含四個元素。
⒊ 重復步驟2,直到所有元素排序完畢。

 public func mergeSort(arr: inout Array<Int>) {
    var tempArr: Array<Array<Int>> = []
    for item in arr {
       var subArr: Array<Int> = []
       subArr.append(item)
       tempArr.append(subArr)
    }
    while tempArr.count != 1 {
        var i = 0
        while i < tempArr.count - 1 {
            tempArr[i] = mergeTowArr(arr1: tempArr[i], arr2: tempArr[i+1])
            tempArr.remove(at : i+1)
            i += 1
        }
    }
 }

private func mergeTowArr(arr1: Array<Int>, arr2: Array<Int>) -> Array<Int> {
    var mergeArr: Array<Int> = []
    var firstIndex = 0
    var secondIndex = 0
    while firstIndex < arr1.count && secondIndex < arr2.count {
        if arr1[firstIndex]  < arr2[secondIndex] {
            merge.append(arr1[firstIndex])
            firstIndex += 1
        }else{
            merge.append(arr2[secondIndex])
            secondIndex += 1
        }
    }
    while firstIndex < arr1.count {
         merge.append(arr1[firstIndex])
         firstIndex += 1
    }
    while secondIndex < arr2.count {
         merge.append(arr2[secondIndex])
         secondIndex += 1
    }
    
    return mergeArr
}

5.選擇排序

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法(比如序列[5, 5, 3]第一次就將第一個[5]與[3]交換,導致第一個5挪動到第二個5后面)

public func selectSort(arr: inout Array<Int>) {
    for i in 0..<arr.count {
        var index = i
        for j in (i + 1)..<arr.count {
            if arr[index] > arr[j] {
                index = j
            }
        }
        if index != i {
            (arr[i],arr[index]) = (arr[index],arr[i])
        }
    }
}

6.堆排序(選擇排序的一種)

通過headMakeFrom將數組arr變為大頂堆,再把大頂堆的第一值和最后一個值交換,數組長度減1。通過heapAdjast將交換后的數組重新排序成大頂堆直到數組長度為0。

public func heapSort(arr: inout Array<Int>) {//時間復雜度O(n*logn)
    var endIndex = arr.count - 1
    headMakeFrom(arr: &arr)

    while endIndex > 0 {
        (arr[0],arr[endIndex]) = (arr[endIndex],arr[0])
        heapAdjast(arr: &arr,starIndex: 1, arrLength: endIndex)
        endIndex -= 1
    }
}


private func heapMakeFrom(arr: inout Array<Int>) {
    var lastHead = arr.count/2
    while lastHead > 0 {
        heapAdjast(arr:  &arr, starIndex: lastHead, arrLenght: arr.count)
        lastHead -= 1
    }
}

private func heapAdjast(arr: Array<Int>, starIndex: Int, arrLength: Int) {
    var temp = arr[starIndex - 1]
    var parentIndex = starIndex
    var childIndex = 2 * parentIndex
    while childIndex <= arrLength {
        if childIndex < arrLength && arr[childIndex] > arr[childIndex - 1] {
            childIndex += 1
        }
        if arr[childIndex-1] > temp {
            arr[parentIndex - 1] = arr[childIndex - 1]
        }else{
            break 
        }
        parentIndex = childIndex
        childIndex = 2 * parentIndex 
    }
    arr[parentIndex - 1] = temp
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容