十大经典排序算法

博主:alc554.comalc554.com03-16252

温馨提示:这篇文章已超过251天没有更新,请注意相关的内容是否还可用!

冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。

func bubbleSort(_ arr: inout [Int]) {    var n = arr.count    for i in 0..<n {        for j in 0..<n-i-1 {            if arr[j] > arr[j+1] {                arr.swapAt(j, j+1)            }        }    }}

选择排序(Selection Sort)

选择排序(Selection-sort)是一种简单直观的排序算法,它首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾,以此类推,直到所有元素均排序完毕。

func selectionSort(_ arr: inout [Int]) {    var n = arr.count    for i in 0..<n-1 {        var minIndex = i        for j in i+1..<n {            if arr[j] < arr[minIndex] {                minIndex = j            }        }        if minIndex!= i {            arr.swapAt(i, minIndex)        }    }}

插入排序(Insertion Sort)

插入排序(Insertion Sort)的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到整个数组有序。

func insertionSort(_ arr: inout [Int]) {    var n = arr.count    for i in 1..<n {        var key = arr[i]        var j = i-1        while j >= 0 && arr[j] > key {            arr[j+1] = arr[j]            j = j-1        }        arr[j+1] = key    }}

希尔排序(Shell Sort)

希尔排序(Shell Sort)是直接插入排序算法的一种更高效的改进版本,但希尔排序是非稳定排序算法。

func shellSort(_ arr: inout [Int]) {    var n = arr.count    gap = n/2    while gap > 0 {        for i in gap..<n {            var key = arr[i]            var j = i-gap            while j >= 0 && arr[j] > key {                arr[j+gap] = arr[j]                j = j-gap            }            arr[j+gap] = key        }        gap = gap/2    }}

归并排序(Merge Sort)

归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

func mergeSort(_ arr: inout [Int], _ l: Int, _ r: Int) {    if l < r {        let m = l + (r-l)/2        mergeSort(&arr, l, m)        mergeSort(&arr, m+1, r)        merge(&arr, l, m, r)    }}func merge(_ arr: inout [Int], _ l: Int, _ m: Int, _ r: Int) {    let n1 = m - l + 1    let n2 = r - m    let L = [Int](repeating: 0, count: n1)    let R = [Int](repeating: 0, count: n2)    for i in 0..<n1 {        L[i] = arr[l+i]    }    for j in 0..<n2 {        R[j] = arr[m+1+j]    }    var i = 0    var j = 0    var k = l    while i < n1 && j < n2 {        if L[i] <= R[j] {            arr[k] = L[i]            i = i + 1        } else {            arr[k] = R[j]            j = j + 1        }        k = k + 1    }    while i < n1 {        arr[k] = L[i]        i = i + 1        k = k + 1    }    while j < n2 {        arr[k] = R[j]        j = j + 1        k = k + 1    }}

快速排序(Quick Sort)

快速排序(Quick Sort)是对冒泡排序的一种改进,它选择基准元素,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

func quickSort(_ arr: inout [Int], _ l: Int, _ r: Int) {    if l < r {        let p = partition(&arr, l, r)        quickSort(&arr, l, p-1)        quickSort(&arr, p+1, r)    }}func partition(_ arr: inout [Int], _ l: Int, _ r: Int) -> Int {    let pivot = arr[r]    let i = (l-1)    for j in l..<r {        if arr[j] <= pivot {            i = i + 1            arr.swapAt(i, j)        }    }    arr.swapAt(i+1, r)    return (i+1)}

堆排序(Heap Sort)

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种,可以利用数组的特点快速定位指定索引的元素。

func heapify(_ arr: inout [Int], _ n: Int, _ i: Int) {    let largest = i    let left = 2 * i + 1    let right = 2 * i + 2    if left < n && arr[left] > arr[largest] {        largest = left    }    if right < n && arr[right] > arr[largest] {        largest = right    }    if largest!= i {        arr.swapAt(i, largest)        heapify(&arr, n, largest)    }}func heapSort(_ arr: inout [Int]) {    let n = arr.count    for i in (n-1..>0).reversed() {        heapify(&arr, n, i)    }    for i in (n-1..>0).reversed() {        arr.swapAt(0, i)        heapify(&arr, i, 0)    }}

计数排序(Counting Sort)

计数排序不是比较排序,排序的速度快于任何比较排序算法,它只能用在数据范围不大的场景中,而且一定是整数。

func countingSort(_ arr: inout [Int], _ max: Int) {    let n = arr.count    let count = [Int](repeating: 0, count: max+1)    for i in 0..<n {        count[arr[i]] = count[arr[i]] + 1    }    for i in 1..<max {        count[i] = count[i] + count[i-1]    }    let sorted = [Int](repeating: 0, count: n)    for i in (n-1)..>=0 {        sorted[count[arr[i]]-1] = arr[i]        count[arr[i]] = count[arr[i]] - 1    }    for i in 0..<n {        arr[i] = sorted[i]    }}

桶排序(Bucket Sort)

桶排序(Bucket Sort)是计数排序的升级版,它利用函数的映射关系,高效与否的关键就在于这个映射函数的确定。

func bucketSort(_ arr: inout [Int], _ max: Int) {    let n = arr.count    let bucket = [Int](repeating: 0, count: max+1)    for i in 0..<n {        bucket[arr[i]] = bucket[arr[i]] + 1    }    for i in 1..<max {        bucket[i] = bucket[i] + bucket[i-1]    }    let sorted = [Int](repeating: 0, count: n)    for i in (n-1)..>=0 {        sorted[bucket[arr[i]]-1] = arr[i]        bucket[arr[i]] = bucket[arr[i]] - 1    }    for i in 0..<n {        arr[i] = sorted[i]    }}

基数排序(Radix Sort)

基数排序(Radix Sort)是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位,有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。

func radixSort(_ arr: inout [Int], _ maxDigit: Int) {    for digit in 1..<maxDigit {        let buckets = [[Int]](repeating: [], count: 10)        for num in arr {            let place = num / (10 ** digit) % 10            buckets[place].append(num)        }        arr = []        for bucket in buckets {            arr.append(contentsOf: bucket)        }    }}
排序算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序$O(n^2)$$O(n)$$O(n^2)$$O(1)$稳定
选择排序$O(n^2)$$O(n^2)$$O(n^2)$$O(1)$不稳定
插入排序$O(n^2)$$O(n)$$O(n^2)$$O(1)$稳定
希尔排序$O(n^{1.5})$$O(n)$$O(n^2)$$O(1)$不稳定
归并排序$O(nlogn)$$O(nlogn)$$O(nlogn)$$O(n)$稳定
快速排序$O(nlogn)$$O(nlogn)$$O(n^2)$$O(logn)$不稳定
堆排序$O(nlogn)$$O(nlogn)$$O(nlogn)$$O(1)$不稳定
计数排序$O(n+k)$$O(n+k)$$O(n+k)$$O(n+k)$稳定
桶排序$O(n+k)$$O(n+k)$$O(n+k)$$O(n+k)$稳定
基数排序$O(d(n+k))$$O(n+k)$$O(n+k)$$O(n+k)$稳定

是十种常见排序算法的平均时间复杂度、最好时间复杂度、最坏时间复杂度、空间复杂度以及稳定性的总结,在实际应用中,需要根据具体情况选择合适的排序算法。

The End

发布于:2025-03-16,除非注明,否则均为十大排行网 - 网罗万象排行,助您明智决策原创文章,转载请注明出处。