Python|Python实现八大经典排序算法

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 -1for 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

【Python|Python实现八大经典排序算法】希尔排序:
def shell_sort(nums): if not isinstance(nums, list) or not nums: return -1n = 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 //=2return 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] = pivotquick_sort(nums, start, left-1) quick_sort(nums, left+1, end) return numsdef 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 -1n = 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 += 1for 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动图图解十大排序算法
如果图解的链接失效的话,请自行到微信公众号“趣谈编程”上自己查看(用搜狗微信搜索功能就可以直接搜)

    推荐阅读