经典排序算法python实现

仅提供python实现与简单注释
排序算法具体介绍请看:
https://www.pythonsky.cn/python/257.html
https://www.cnblogs.com/onepixel/p/7674659.htm
https://blog.csdn.net/Dby_freedom/article/details/82154869

排序算法性能指标
常用排序算法性能指标
排序算法分类
排序算法归类
冒泡排序

def bubbleSort(nums):
    n = len(nums)
    k = n-1
    for i in range(n-1):
        flag = False #指示该趟排序是否交换
        for j in range(k):
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
                k = j #最后一次发生交换的位置,nums[k]后的数据都为有序
                flag = True #发生交换
        if not flag: break #无交换代表数组有序,则提前终止排序
    return nums

选择排序

def selectionSort(nums):
    n = len(nums)
    for i in range(n-1):
        k = i #代表[i,n-1]内最小值下标,每趟把该范围内的最小值交换到位置i
        for j in range(i+1, n):
            if nums[j] < nums[k]:
                k = j #找到更小的值,更改下表
        nums[i], nums[k] = nums[k], nums[i] #发生一趟交换
    return nums

插入排序1:简单插入排序

def insertionSort(nums):
    n = len(nums)
    for i in range(1,n):
        tmp = nums[i]#保存当前位置的值
        j = i
        while j and nums[j-1] > tmp:#所有大于nums[i]的值后移一位
            nums[j] = nums[j-1]
            j -= 1
        nums[j] = tmp #nums[i]移动到正确位置
    return nums

插入排序2:希尔排序

def shellSort(nums):
    n = len(nums)
    gap = n//2 #把数组分成gap组,相隔距离为gap的值在同一组
    while gap >= 1: #gap为1时执行最后一趟排序
        for i in range(gap,n):
            tmp = nums[i]
            j = i
            while j and nums[j-gap] > tmp: #以gap为间隔执行简单插入排序
                nums[j] = nums[j-gap]
                j -= gap
            nums[j] = tmp
        gap // 2 #gap减半
    return nums

快速排序

def quickSort(nums,l,r):
    def partition(nums,l,r):
        i,j = l,r
        while i<j: 
        #选取最左的值为标兵,则开始移动必须为最右,确保nums[i]<=nums[l]             	
        	while i<j and nums[j] >= nums[l]: j-=1
            while i<j and nums[i] <= nums[i]: i+=1
            nums[i], nums[j] = nums[j], nums[i]
        nums[l], nums[i] = nums[i], nums[l]#标兵交换至中间位置
        return i
    
    if l >= r: return
    mid = partition(nums,l,r)
    quickSort(nums,l, mid-1)#递归排序标兵左边数组
    quickSort(nums, mid+1,r)#递归排序标兵右边数组
    
    return nums

归并排序

def mergeSort(nums):
    def merge(nums1,nums2):#常规的合并有序数组
        nums = []
        L1,L2 = len(nums1),len(nums2)
        i = j = 0
        while i<L1 and j<L2:
            if nums1[i] <= nums2[j]: 
                nums.append(nums1[i])
                i += 1
            else:
                nums.append(nums2[j])
                j += 1
        if i < L1:
            nums += nums1[i:]
        if j < L2:
            nums += nums2[j:]
        return nums
            
    n = len(nums)
    if n <= 1: return nums
    nums1 = mergeSort(nums[:n//2])#递归排序左半数组
    nums2 = mergeSort(nums[n//2:])#递归排序右半数组
    nums = merge(nums1,nums2)#合并两个有序数组
    
    return nums

计数排序

def countingSort(nums):
    n = len(nums)
    if not n: return []
    minval = maxval = nums[0]
    for num in nums:#寻找数组内最小值与最大值
        minval = min(minval, num)
        maxval = max(maxval, num)
    counter = {}#使用哈希表记录,但貌似一般的计数排序不使用哈希表
    for num in nums:#计数
        if num in counter:
            counter[num] += 1
        else:
            counter[num] = 1
    nums = []
    for num in range(minval, maxval+1):#从最小到最大遍历
        if num in counter:#存在则添加至有序数组
            n = counter[num]
            nums += [num]*n
    return nums

基数排序

def radixSort(nums):
    maxval = nums[0]
    n = len(nums)
    for i in range(1,n):#寻找最大值
        maxval = max(maxval, nums[i])
    
    k = 0
    while maxval:#计算最大值的位数
        maxval //= 10
        k += 1
    for i in range(k):
        radix = [[]for _ in range(10)]#0-9共10个基数数组
        divisor = 10**i
        surplus = 10*divisor
        for num in nums:
            j = (num%surplus)//divisor #右往左提取第i+1位
            radix[j].append(num)#加入对应基数数组
        nums = []
        for idx,rad in enumerate(radix):#对每个基数数组进行计数排序
            if rad == []: continue
            nums  += countingSort(rad)
    return nums
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值