Python实现八大经典排序算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yinhui_zhang/article/details/88670313

1、写在前面的话

       本篇博客并不涉及到排序算法的理论讲解,具体理论可以参考reference的链接,并且强烈推荐数据结构和算法的可视化网站【0】。本文给出八种经典的排序算法的Python实现代码和部分注解,算是一个总结,也感谢网络众多优秀的博主分享他们的idea,站在巨人的肩膀上果然成长很迅速。排序可以说在经典算法中是很重要的一部分,对于常见的排序算法要做到本能的敲出代码,了解各种算法的时间复杂度和空间复杂度,关于时间复杂度和空间复杂度具体可以参考【1】。对于外部排序和线性时间的排序也请参考reference的链接。对于稳定性的判断,请记住口诀,不稳定:快选堆希  稳定:插冒归基。

2、Show me the code

冒泡排序:

def bubble(nums):
    if not isinstance(nums, list) or not nums:
        return -1
    #i控制几趟
    for i in range(1, len(nums)):
        # len(nums)-i因为最后有排好的数字
        for j in range(0, len(nums)-i):
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
    return nums

选择排序:

def select(nums):
    if not isinstance(nums, list) or not nums:
        return -1  

    for i in range(len(nums)-1):
        min_index = i
        # i+1 是开始从i之后的元素找到最小值,并用minindex标记上
        for j in range (i+1, len(nums)):
            if nums[j] < nums[min_index]:
                min_index = j
        #如果和最开始的标记的最小元素不等,就交换两个元素
        if min_index != i:
            nums[i], nums[min_index] = nums[min_index], nums[i]
    return nums

插入排序:


def insertionSort(nums):
    if not isinstance(nums, list) or not nums:
        return -1

    #i是控制处理的第几个元素
    for i in range(1,len(nums)):
        for j in range(i, 0, -1):
            # 如果比前面的元素小,则往前移动
            if nums[j] < nums[j-1]:
                nums[j], nums[j-1] = nums[j-1], nums[j]
            # 否则代表比前面的所有元素都小,不需要再移动
            else:
                break
    return nums

希尔排序:


def shell_sort(nums):
    if not isinstance(nums, list) or not nums:
        return -1

    n = len(nums)
    gap = n//2   #定义增量
    #gap等于一的时候相当于最后一步是一插入排序
    while gap >=1:
        for j in range(gap, n):
            i = j
            #增量的插入排序版本
            while (i-gap)>=0:
                if nums[i] < nums[i-gap]:
                    nums[i], nums[i-gap] = nums[i-gap], nums[i]
                    i -= gap
                else:
                    break
        gap //=2

    return nums

快速排序:

def quick_sort(nums, start, end):
    if start >= end:
        return 
    pivot = nums[start]
    left = start
    right = end
    while left < right:
        while left < right and nums[right] >= pivot:
            right -= 1
        nums[left] = nums[right]
        while left < right and nums[left] < pivot:
            left += 1
        nums[right] = nums[left]
    nums[left] = pivot
    
    quick_sort(nums, start, left-1)
    quick_sort(nums, left+1, end)
    return nums

    
def quick_sort(nums):
    if len(nums) < 2:
        return nums
    else:
        midpivot = nums[0]
        less_before_midpivot = [i for i in nums[1:] if i <= midpivot]
        bigger_before_midpivot = [i for i in nums[1:] if i > midpivot]
        finnal_nums = quick_sort(less_before_midpivot) + [midpivot] + quick_sort(bigger_before_midpivot)
        return finnal_nums

归并排序:

def merge_sort(nums):
    if not isinstance(nums, list) or not nums:
        return -1
    
    n = len(nums)
    if n == 1:
        return nums
    mid = n//2
    left_list = merge_sort(nums[: mid])
    right_list = merge_sort(nums[mid:])
    return merge(left_list, right_list)

def merge(left_list, right_list):
    left , right =0, 0
    merge_result = []
    while left < len(left_list) and right < len(right_list):
        if left_list[left] <= right_list[right]:
            merge_result.append(left_list[left])
            left += 1
        else:
            merge_result.append(right_list[right])
            right += 1
    merge_result += left_list[left:]
    merge_result += right_list[right:]
    
    return merge_result

堆排序:

#nums的0位是无效
def heap_sort(nums):
    N = len(nums)-1
    buildHeap(nums)
    for i in range(1,N):
        deleteMin(nums, N+1-i)
    return nums[:0:-1]

def deleteMin(nums, heap_size):
    swap(nums, 1, heap_size)
    heap_size -=1
    sink(nums, 1, heap_size)
    
        
def buildHeap(nums):
    heap_size = len(nums) -1    
    for i in range(heap_size//2 ,0 ,-1):
        sink(nums, i, heap_size)
        
        
def sink(nums, parentIndex, heap_size):
    if parentIndex*2 > heap_size:
        return
    minNodeIndex = minIndex(nums, parentIndex, heap_size)
    if minNodeIndex != parentIndex:
        swap(nums, minNodeIndex, parentIndex)
        sink(nums, minNodeIndex, heap_size)
        
        
def swap(nums, i , j):
    nums[i] , nums[j] = nums[j], nums[i]
    
    
def minIndex(nums, parentIndex, heap_size):
    minIndex = parentIndex
    leftIndex = 2*parentIndex
    if leftIndex <= heap_size:
        minIndex = leftIndex if nums[leftIndex] < nums[parentIndex] else parentIndex
    rightIndex = 2*parentIndex+1
    if rightIndex <= heap_size:
        minIndex = rightIndex if nums[rightIndex] < nums[minIndex] else minIndex      
    return minIndex

基数排序:

def RadixSort(nums):
    #就算n为了计算最高位
    max_num = max(nums)
    n = 1 
    while max_num > 10**n:
        n += 1
        
    for k in range(n):
        #初始化0-9个桶来排序呢
        buckets = [[] for i in range(10)]
        for subnum in nums:
            buckets[int(subnum/(10**k)%10)].append(subnum)
        nums = [num for bucket in buckets for num in bucket ]
    return nums

【0】https://visualgo.net/zh

【1】时间复杂度和空间复杂度速查表

【2】图解冒泡排序

【3】图解选择排序

【4】图解插入排序

【5】图解希尔排序

【6】图解快速排序

【7】图解归并排序

【9】图解堆排序

【10】图解基数排序

【11】 Python的线性时间排序--计数排序 桶排序 基排序

【12】外部排序

【13】github动图图解十大排序算法

如果图解的链接失效的话,请自行到微信公众号“趣谈编程”上自己查看(用搜狗微信搜索功能就可以直接搜)

猜你喜欢

转载自blog.csdn.net/yinhui_zhang/article/details/88670313