---页首---

排序算法-快速排序

快速排序(选择升序排序)

  • 思路
      1. 从序列中选择一个枢轴(支点,pivot),假设每次选择索引0位置为支点
      1. 利用支点将序列分割成两个子队列
        小于支点的放在支点的左侧
        大于支点的放在支点的右侧
        等于支点的左右都可以(这里相等放右边)
      1. 对子序列进行1,2操作,直到不能再分割(也就是子序列只剩下1个元素)
class QuickSort {
    
    var array = [5, 7, 2, 8, 9, 4, 7, 3, 2]
    
    func sort() {
        let begin = 0
        let end = array.count
        sort(begin: begin, end: end)
    }
    
    // 对 [begin, end) 元素快速排序
    func sort(begin: Int, end: Int) {
        if end - begin < 2 { return }
        // 确定支点的位置
        let pivot = pivotIndex(begin: begin, end: end)
        // 对子序列进行快速排序
        sort(begin: begin, end: pivot)
        sort(begin: pivot + 1, end: end)
    }
    
    /// 构造 [begin, end) 范围的支点元素,返回支点元素的最终位置
    private func pivotIndex(begin: Int, end: Int) -> Int {
        var b = begin, e = end
        // 备份 begin 位置的元素
        let pivot = array[b]
        // 右开区间,end - 1 指向最后一个元素
        e -= 1
        while b < e {
            while b < e {
                if pivot < array[e] { // 右边元素大
                    e -= 1
                } else { // 右边 <= 支点,将元素放入左边,换方向遍历
                    array[b] = array[e]
                    b += 1
                    break
                }
            }
            while b < e {
                if pivot > array[b] { // 左边 < 支点
                    b += 1
                } else { // 左边 >= 支点,将元素放入右边,换方向遍历
                    array[e] = array[b]
                    e -= 1
                    break
                }
            }
        }
        // 说明 begin == end,将支点元素放入最终位置
        array[e] = pivot // 等价 array[begin] = pivot
        // 返回支点元素的位置
        return e
    }
}
let qs = QuickSort()
qs.sort()
print(qs.array) // [2, 2, 3, 4, 5, 7, 7, 8, 9]

最好、平均时间复杂度: O(nlogn), 最坏时间复杂度: O(n^2)

空间复杂度:O(logn)

稳定性:不稳定排序

posted @ 2020-04-17 15:54  20190311  阅读(118)  评论(0编辑  收藏  举报
---页脚---