十大排序算法

算法说明

十大排序算法分别是:

冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

Python版本

#!/usr/bin/python
# coding=utf-8


import sys
import os
import math

def bubbleSort(arr):
    '''
    冒泡排序
    '''
    length = len(arr)
    if length < 2:
        return arr

    for i in range(1, length, 1):
        for j in range(0, length-i, 1):
            if arr[j] > arr[j+1]:
                # arr[j],arr[j+1] = arr[j+1],arr[j]
                arr[j] = arr[j] + arr[j+1]
                arr[j+1] = arr[j] - arr[j+1]
                arr[j] = arr[j] - arr[j+1]
    # print("冒泡排序:" + str(arr))
    print("bubbleSort:" + str(arr))
    return arr

def selectSort(arr):
    '''
    选择排序
    '''
    length = len(arr)
    if length < 2:
        return arr

    for i in range(0, length):
        index = i
        for j in range(i+1, length):
            if arr[j] < arr[index]:
                index = j
        if index != i:
            arr[i],arr[index] = arr[index],arr[i]
    # print("选择排序:" + str(arr))
    print("selectSort:" + str(arr))
    return arr

def insertSort(arr):
    '''
    插入排序
    '''
    length = len(arr)
    if length < 2:
        return arr

    gap = 1
    for i in range(0, length):
        index = i-gap
        value = arr[i]
        while index >= 0:
            if arr[index] > value:
                arr[index+1] = arr[index]
                index -= 1
            else:
                break
        # while index >= 0 and arr[index] > value:
        #   arr[index+1] = arr[index]
        #   index -= 1
        arr[index+1] = value
    # print("插入排序:" + str(arr))
    print("insertSort:" + str(arr))
    return arr

def shellSort(arr):
    '''
    希尔排序
    '''
    lenght = len(arr)
    if lenght < 2:
        return arr

    gap = lenght//2
    while gap > 0:
        for i in range(0,lenght):
            index = i - gap
            value = arr[i]
            while index >= 0 and arr[index]>value:
                arr[index+gap] = arr[index]
                index -= gap
            arr[index+gap] = value
        gap = gap//2
    # print("希尔排序:" + str(arr))
    print(" shellSort:" + str(arr))
    return arr

def mergeSort(arr):
    '''
    归并排序
    '''
    def mergeData(left,right):
        result = []
        while len(left)>0 and len(right):
            if left[0] > right[0]:
                result.append(right.pop(0))
            else:
                result.append(left.pop(0))
        while len(left)>0:
            result.append(left.pop(0))
        while len(right)>0:
            result.append(right.pop(0))
        return result
    
    def devide(arr):
        length = len(arr)
        if length < 2:
            return arr
        middle = length//2
        left = arr[0:middle]
        right = arr[middle:length]
        return mergeData(devide(left),devide(right))

    length = len(arr)
    if length < 2:
        return arr
    result = devide(arr)
    # print("归并排序:" + str(result))
    print(" mergeSort:" + str(result))
    return result

def quickSort(arr):
    '''
    快速排序
    '''
    def pivotSort(arr,start,end):
        pivotValue = arr[end]
        index = start
        j = start
        while j < end:
            if arr[j] < pivotValue:
                arr[index],arr[j] = arr[j],arr[index]
                index += 1
            j += 1
        arr[index],arr[end] = arr[end],arr[index]
        return index

    def pivotSort2(arr,start,end):
        pivot = arr[start]
        while start < end:
            while start < end and arr[end] > pivot:
                end -= 1
            arr[start] = arr[end]
            while start < end and arr[start] <= pivot:
                start += 1
            arr[end] = arr[start]
        arr[start] = pivot
        return start
      
    def pivotSort3(arr,left,right):
        #默认以第一个为基准点
        pivot = arr[left]
        start = left
        end = right
        while start != end:
            while start < end and arr[end] > pivot:
                end -= 1
            while start < end and arr[start] <= pivot:
                start += 1
            #交换左右指针指向的值,使得左右指针能够继续相向移动
            if start < end:
                arr[start],arr[end] = arr[end],arr[start]
        #当左右指针重合时,交换左指针与基准点的值
        arr[left] = arr[start]
        arr[start] = pivot
        return start

    def quickSortStart(arr,start,end):
        if start < end:
            # pivotIndex = pivotSort(arr,start,end)
            # pivotIndex = pivotSort2(arr,start,end)
            pivotIndex = pivotSort3(arr,start,end)
            quickSortStart(arr,start,pivotIndex-1)
            quickSortStart(arr,pivotIndex+1,end)
        return arr

    length = len(arr)
    if length < 2:
        return arr
    result = quickSortStart(arr,0,len(arr)-1)
    # print("快速排序:" + str(result))
    print(" quickSort:" + str(result))
    return result

def heapSort(arr):
    '''
    堆排序
    '''
    arrLength = len(arr)
    if arrLength < 2:
        return arr

    def swap(arr,i,j):
        arr[i],arr[j] = arr[j],arr[i]

    def heapify(arr,i):
        left = 2*i + 1
        right = 2*i + 2
        largest = i
        if left < arrLength and arr[left] > arr[largest]:
            largest = left
        if right < arrLength and arr[right] > arr[largest]:
            largest = right
        if largest != i:
            swap(arr,i,largest)
            heapify(arr,largest)

    def buildMaxHeap(arr):
        # for i in range(math.floor(len(arr)/2),-1,-1):
        for i in range(len(arr)/2,-1,-1):
            heapify(arr,i)

    buildMaxHeap(arr)
    for i in range(len(arr)-1,0,-1):
        swap(arr,0,i)
        arrLength -= 1
        heapify(arr,0)
    # print("    堆排序:" + str(arr))
    print("  heapSort:" + str(arr))
    return arr

def countSort(arr):
    '''
    计数排序
    '''
    arrLength = len(arr)
    if arrLength < 2:
        return arr

    minValue = 0
    maxValue = 0
    for item in arr:
        minValue = min(minValue,item)
        maxValue = max(maxValue,item)
    # 计算得到临时数组的长度
    bucketLen = (maxValue - minValue) + 1
    # 初始化临时数组
    bucket = [0 for i in range(bucketLen)]
    # 源数组的值为key,出现次数为value存储到临时数组
    for item in arr:
        bucket[item-minValue] += 1
    # 新建结果数组
    result = [0 for i in range(arrLength)]
    index = 0
    for i in range(0,bucketLen):
        while bucket[i] > 0:
            result[index] = i+minValue
            index += 1
            bucket[i] -= 1
    # print("  计数排序:" + str(result))
    print(" countSort:" + str(result))
    return result

def bucketSort(arr):
    '''
    桶排序
    '''
    arrLength = len(arr)
    if arrLength < 2:
        return arr
    minValue = 0
    maxValue = 0
    for item in arr:
        minValue = min(minValue,item)
        maxValue = max(maxValue,item)
    # 计算得到桶数量
    bucketNum = (maxValue - minValue)/arrLength + 1
    # 初始化桶
    # bucket = [[]]*n操作中,只是创建n个指向list的引用,一旦list改变,bucket中n个list也会随之改变。
    # 需要使用间接定义的方式创建二维数组
    bucket = [[] for i in range(bucketNum)]
    # 将源数组的元素放入各个桶中
    for item in arr:
        num = (item - minValue)/arrLength
        currentBucket = bucket[num]
        currentBucket.append(item)
    # 各个桶中元素排序
    for item in bucket:
        quickSort(item)
    # 获取所有桶排序后的数据
    index = 0
    for item in bucket:
        for value in item:
            arr[index] = value
            index += 1
    print("bucketSort:" + str(arr))
    return arr

def radixSort(arr):
    '''
    基数排序
    '''
    arrLength = len(arr)
    if arrLength < 2:
        return arr
    def getMax(arr):
        maxValue = arr[0]
        for item in arr:
            maxValue = max(item,maxValue)
        return maxValue

    def digitsCountSort(arr,exp):
        # 存储"被排序数据"的临时数组
        output = [0 for i in range(arrLength)]
        # 每一位的数字只能是[0-9),所以默认新建长度为10的数组
        bucket = [0 for i in range(10)]
        # 源数组当前为数的值为key,出现次数为value存储到临时数组
        for i in range(0,arrLength):
            num = (arr[i]/exp)%10
            bucket[num] += 1
        # 这里修改后使得buckets[i]的值就是排序后该数据在源数组中应处的位置
        for i in range(1,10):
            bucket[i] += bucket[i-1]
        # 将数据存储到临时数组output[]中
        for i in range(arrLength-1,-1,-1):
            num = (arr[i]/exp)%10
            output[bucket[num]-1] = arr[i]
            bucket[num] -= 1
        # 将排序好的数据赋值给a[]
        for i in range(0,arrLength):
            arr[i] = output[i]

    maxValue = getMax(arr)
    # 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
    exp = 1
    while maxValue/exp > 0:
        #从个位数开始,对数组按exp位数进行桶排序
        digitsCountSort(arr,exp)
        exp = exp * 10
    print(" radixSort:" + str(arr))
    return arr

Swift版本

class Sort: NSObject {
    
    /// 冒泡排序
    static func bubbleSort(_ data:Array<Int>)->Any{
        var dataAry:Array<Int> = data
        let num = dataAry.count - 1
        if num < 1 {
            return dataAry
        }
        for i in 1...num {
            for j in 0...(num-i) {
                if dataAry[j] > dataAry[j+1] {
                    let temp = dataAry[j+1]
                    dataAry[j+1] = dataAry[j]
                    dataAry[j] = temp
                }
            }
        }
        print("冒泡排序:",dataAry)
        return dataAry
    }
    
    /// 选择排序
    static func selectSort(_ data:Array<Int>)->Any {
        var dataAry:Array<Int> = data
        let num = dataAry.count - 1
        if num < 1 {
            return dataAry
        }
        
        for i in 0...num-1 {
            var index:Int = i
            for j in i+1...num {
                if dataAry[j] < dataAry[index] {
                    index = j
                }
            }
            if index != i {
                let temp = dataAry[i]
                dataAry[i] = dataAry[index]
                dataAry[index] = temp
            }
        }
        print("选择排序:",dataAry)
        return dataAry
    }
    
    /// 插入排序
    static func insertSort(_ data:Array<Int>) -> Any {
        var dataAry:Array<Int> = data
        let num = dataAry.count - 1
        if num < 1 {
            return dataAry
        }
        for i in 0...num {
            let value = dataAry[i]
            var index = i-1
            while index >= 0 {
                if dataAry[index] > value {
                    dataAry[index+1] = dataAry[index]
                    index -= 1
                }else{
                    break
                }
            }
            dataAry[index+1] = value
        }
        print("插入排序:",dataAry)
        return dataAry
    }
    
    /// 希尔排序
    static func shellSort(_ data:Array<Int>)->Any {
        var dataAry:Array<Int> = data
        let num = data.count - 1
        if num < 1 {
            return dataAry
        }
        var gap = num/2
        while gap > 0 {
            for i in 0...num {
                let value = dataAry[i]
                var index = i - gap
                while index >= 0 {
                    if dataAry[index] > value {
                        dataAry[index+gap] = dataAry[index]
                        index -= gap
                    }else{
                        break
                    }
                }
                dataAry[index+gap] = value
            }
            gap = gap/2
        }
        print("希尔排序:",dataAry)
        return dataAry
    }
    
    /// 归并排序
    static func mergeSort(_ data:Array<Int>)->Any {
        let dataAry:Array<Int> = data
        let num = data.count - 1
        if num < 1 {
            return dataAry
        }
        
        func mergeData(_ left:Any, _ right:Any)->Any {
            var result:Array<Int> = []
            var leftData:Array<Int> = left as! Array<Int>
            var rightData:Array<Int> = right as! Array<Int>
            while leftData.count > 0 && rightData.count > 0 {
                if leftData[0] > rightData[0] {
                    result.append(rightData.first!)
                    rightData.remove(at: 0)
                }else{
                    result.append(leftData.first!)
                    leftData.remove(at: 0)
                }
            }
            while leftData.count > 0 {
                result.append(leftData.first!)
                leftData.remove(at: 0)
            }
            while rightData.count > 0 {
                result.append(rightData.first!)
                rightData.remove(at: 0)
            }
            return result
        }
        
        func devideData(_ array:Array<Int>)->Any {
            if array.count < 2 {
                return array
            }
            let middle = array.count/2
            var left:Array<Int> = []
            var right:Array<Int> = []
            for i in 0...(array.count-1) {
                if i < middle {
                    left.append(array[i])
                }else{
                    right.append(array[i])
                }
            }
            return mergeData(devideData(left),devideData(right))
        }
        
        let result = devideData(dataAry)
        print("归并排序:",result)
        return result
    }
    
    /// 快速排序
    static func quickSort(_ data:Array<Int>)->Any {
        let num = data.count - 1
        if num < 1 {
            return data
        }
        
        func swap(data: inout Array<Int>, i:Int, j:Int) {
            let temp = data[i]
            data[i] = data[j]
            data[j] = temp
        }
        //挖坑法
        func findPoint(result: inout Array<Int>, start:Int, end:Int)->Int {
            let value = result[start]
            var left = start
            var right = end
            while left < right {
                while left < right && result[right] > value {
                    right -= 1
                }
                result[left] = result[right]
                while left < right && result[left] <= value {
                    left += 1
                }
                result[right] = result[left]
            }
            result[left] = value
            return left
        }
        //前后指针法
        func findPoint2(result: inout Array<Int>, start:Int, end:Int)->Int {
            //取队尾为桩
            let value = result[end]
            var i = start
            var index = start
            while i < end {
                if result[i] < value {
                    swap(data: &result, i: i, j: index)
                    index += 1
                }
                i += 1
            }
            swap(data: &result, i: end, j: index)
            return index
            
//            //取队头为桩
//            let pivot = result[start]
//            var index = start + 1
//            var i = index
//            while  i <= end {
//                if result[i] < pivot {
//                    swap(data:&result, i:i, j:index)
//                    index += 1
//                }
//                i += 1
//            }
//            swap(data:&result,i:start,j:index-1)
//            return index-1
        }
        
        func quickSortStart(_ data: inout Array<Int>, _ start:Int, _ end:Int)->Any {
            if start < end {
                let pivotIndex = findPoint(result: &data, start: start, end: end)
//                let pivotIndex = findPoint2(result: &data, start: start, end: end)
                data = quickSortStart(&data, start, pivotIndex-1) as! Array<Int>
                data = quickSortStart(&data, pivotIndex+1, end) as! Array<Int>
            }
            return data
        }
        
        var dataAry:Array<Int> = data
        let result = quickSortStart(&dataAry,0,num)
        print("快速排序:",result)
        return result
        
        
    }
    
    /// 堆排序
    static func heapSort(_ data:Array<Int>)->Any {
        var dataAry:Array<Int> = data
        if dataAry.count < 2 {
            return dataAry
        }
        var arrLength = data.count
        
        func swap(data: inout Array<Int>, i:Int, j:Int) {
            let temp = data[i]
            data[i] = data[j]
            data[j] = temp
        }
        
        func heapify(_ data: inout Array<Int>, _ i:Int) {
            let left = 2*i + 1
            let right = 2*i + 2
            var largest = i
            if left < arrLength && data[left] > data[largest] {
                largest = left
            }
            if right < arrLength && data[right] > data[largest] {
                largest = right
            }
            if largest != i {
                swap(data: &data, i: i, j: largest)
                heapify(&data, largest)
            }
        }
        
        func buildHeap(_ data: inout Array<Int>) {
            for i in (0..<data.count/2).reversed() {
                heapify(&data, i)
            }
        }
        
        buildHeap(&dataAry)
        for i in (1..<dataAry.count).reversed() {
            swap(data: &dataAry, i: 0, j: i)
            arrLength -= 1
            heapify(&dataAry, 0)
        }
        
        print("堆 排 序: \(dataAry)")
        return dataAry
    }
    
    /// 计数排序
    static func countSort(_ data:Array<Int>)->Any {
        let dataAry:Array<Int> = data
        if dataAry.count < 2 {
            return dataAry
        }
        //计算最大最小值,得到临时数组的长度
        var minValue = 0
        var maxValue = 0
        for item in dataAry {
            minValue = min(minValue, item)
            maxValue = max(maxValue, item)
        }
        let tempLen = maxValue - minValue + 1
        //初始化临时数组
        var temp:Array<Int> = [Int].init(repeating: 0, count: tempLen)
        //源数组的值为key,出现次数为value存储到临时数组
        for item in dataAry {
            temp[item-minValue] += 1
        }
        //初始化结果数组
        var result:Array<Int> = [Int].init(repeating: 0, count: dataAry.count)
        var index = 0
        for i in 0..<tempLen {
            while temp[i] > 0 {
                result[index] = i + minValue
                index += 1
                temp[i] -= 1
            }
        }
        print("计数排序: \(result)")
        return result
    }
    
    /// 桶排序
    static func bucketSort(_ data:Array<Int>)->Any {
        var dataAry:Array<Int> = data
        let dataLength = dataAry.count
        
        if dataLength < 2 {
            return dataAry
        }
        //计算最大最小值,得到桶数量
        var minValue = 0
        var maxValue = 0
        for item in dataAry {
            minValue = min(minValue, item)
            maxValue = max(maxValue, item)
        }
        //计算桶的数量
        let bucketNum = (maxValue - minValue) / dataLength + 1
        var bucketArr:Array<Array<Int>> = [Array].init(repeating: [Int](), count: bucketNum)
        //将源数组元素放入各个桶中
        for item in dataAry {
            let num = (item - minValue)/dataLength
            bucketArr[num].append(item)
        }
        //各个桶中元素进行排序(快排)
        for i in 0..<bucketNum {
            let bucketResult:Array<Int> = quickSort(bucketArr[i]) as! Array<Int>
            //桶内数据排序时做了深拷贝,这里需要替换排序好的桶
            bucketArr[i] = bucketResult
        }
        //将所有桶中元素取出
        var index = 0
        for item in bucketArr {
            for i in 0..<item.count {
                dataAry[index] = item[i]
                index += 1
            }
        }
        print(" 桶 排序: \(dataAry)")
        return dataAry
    }
    
    /// 基数排序
    static func radixSort(_ data:Array<Int>)->Any {
        var dataAry:Array<Int> = data
        if dataAry.count < 2 {
            return dataAry
        }
        
        func digitsSort(_ data: inout Array<Int>, _ exp:Int)->Any {
            // 存储本次排序结果的临时数组
            var result:Array<Int> = Array.init(repeating: 0, count: data.count)
            // 用于排序的桶,由于每一位的数字只能是[0-9),所以默认新建长度为10的数组
            var bucket:Array<Int> = Array.init(repeating: 0, count: 10)
            // 源数组每一项数据当前位数的值为key,出现次数为value存储到桶中
            for item in data {
                bucket[(item/exp)%10] += 1
            }
            // 这里修改后使得buckets[i]的值就是排序后该数据在源数组中应处的位置
            for i in 1..<bucket.count {
                bucket[i] += bucket[i-1]
            }
            for i in (0..<data.count).reversed() {
                let num = (data[i]/exp)%10
                result[bucket[num]-1] = data[i]
                bucket[num] -= 1
            }
            for i in 0..<data.count {
                data[i] = result[i]
            }
            return data
        }
        
        let maxValue:Int = { () -> Int in
            var value = dataAry[0]
            for item in dataAry {
                value = max(item, value)
            }
            return value
        }()
        // exp:排序位数,各位1,十位1*10...
        var exp = 1
        while maxValue/exp > 0 {
            dataAry = digitsSort(&dataAry, exp) as! Array<Int>
            exp *= 10
        }
        print("基数排序: \(dataAry)")
        return dataAry
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 浙大 MOOC 数据结构 复杂度分析 排序算法平均时间复杂度最差时间复杂度空间复杂度数据对象稳定性冒泡排序稳定选择...
    学而不思会忘阅读 661评论 0 1
  • 简单排序 冒泡排序:循环遍历左右比较,较小者左移或较大者后移; 选择排序:在未排序序列中找到最小者元素一次放到已排...
    王然Gondole阅读 1,423评论 0 2
  • 原文链接https://zhuanlan.zhihu.com/p/57088609 说明 十大排序算法可以说是每个...
    铁甲万能狗阅读 299评论 0 1
  • 排序算法可以分为内部排序和外部排序.内部排序是数据记录在内存中进行排序外部排序是因排序的数据很大,一次不能容纳全部...
    coder_girl阅读 909评论 1 1
  • 0 算法概述0.1 算法分类十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时...
    洪荒之人阅读 582评论 0 0