swift实现常用排序算法

36 阅读2分钟

选择排序

// 平均时间复杂度:O(n2)
// 最好情况:O(n2)    
// 最坏情况:O(n2)
// 空间复杂度:O(1)
// 稳定性:稳定
func selectSort(arr: inout [Int]) {
    let count = arr.count
    for i in 0..<count {
        var min = i
        // 内层循环,每次找出未排序列表中最小的值
        for j in i+1..<count {
            if arr[j] < arr[min] {
                min = j
            }
        }
        if min != i {
            arr.swapAt(min, i)
        }
    }
}

冒泡排序

// 平均时间复杂度:O(n2)
// 最好情况:O(n)    最坏情况:O(n2)
// 空间复杂度:O(1)
// 稳定性:稳定
func bubbleSort(arr: inout [Int]) {
    for i in 0..<arr.count {
        for j in 0..<arr.count - i - 1 {
            if arr[j + 1] < arr[j] {
                arr.swapAt(j + 1, j)
            }
        }
    }
}

插入排序

插入排序是一种直观且简单的排序算法,核心思想是将元素逐个插入到已排序的序列中合适的位置,就像整理手中的扑克牌一样 —— 每次拿起一张牌,插入到前面已经排好序的牌中正确的位置。

  • 优点

    • 简单易懂,实现方便。
    • 近乎有序的数组效率很高(时间复杂度接近 O(n))。
    • 空间复杂度为 O(1)(原地排序,不需要额外空间)。
    • 稳定排序(相等元素的相对顺序不变)。
  • 缺点

    • 对大规模无序数组效率较低,时间复杂度为 O(n²)(最坏和平均情况)。
    • 元素移动次数较多(每次插入可能需要移动多个元素)
// 平均时间复杂度:O(n2)
// 最好情况:O(n)    最坏情况:O(n2)
// 空间复杂度:O(1)
// 稳定性:稳定
func insertSort(arr: inout [Int]) {
    let count = arr.count
    for i in 1..<count {
        var j = i - 1
        let key = arr[i] // 当前要排序的元素
        // 将当前元素与已排序部分的元素从后向前比较
        while j >= 0 && key < arr[j] {
            arr[j + 1] = arr[j] // 元素后移
            j -= 1
        }
        arr[j + 1] = key
    }
}

快速排序


// 时间复杂度:  平均 O(NlogN),最坏 O(N2)(如果每次选择的枢轴都不理想)
// 空间复杂度:  O(logN)(主要是递归栈开销)
// 原地排序: 不需要额外的数组空间
func quickSort(arr: inout [Int], low: Int, high: Int) {
    guard !arr.isEmpty else {
        return
    }
    if low >= high {
        return
    }
    let part = getPart(arr: &arr, low: low, high: high)
    
    quickSort(arr: &arr, low: 0, high: part - 1)
    quickSort(arr: &arr, low: part + 1, high: high)
}

func getPart(arr: inout [Int], low: Int, high: Int) -> Int {
    
    let pivot = arr[low]
    
    var i = low + 1
    var j = high
    
    while i <= j {
        //寻找大于pivot的元素,找到后交换
        while i < high && arr[i] <= pivot {
            i += 1
        }
        //寻找小于pivot的元素,找到后交换
        while j > low && arr[j] > pivot {
            j -= 1
        }
        if i >= j {
            break
        }
        // 交换
        arr.swapAt(i, j)
    }
    arr.swapAt(low, j)
    return j
}

var arr = [4, 1, 7, 2, 5, 3, 6]
quickSort(arr: &arr, low: 0, high: arr.count - 1)