python实现七大经典排序算法

本文主要使用python来实现七个经典的排序算法,分别是:冒泡排序、选择排序,插入排序,快速排序,希尔排序,堆排序和归并排序。


一、相关归纳总结



1、时间复杂度

O(N^2): 冒泡排序、选择排序,插入排序

O(N*logN): 快速排序,希尔排序,堆排序和归并排序

2、空间复杂度

O(1):插入排序,冒泡排序,选择排序,堆排序,希尔排序

O(logN)~O(N):快速排序

O(N):归并排序

3、稳定性:

若待排序的序列中,存在多个相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;若经过排序后,记录的相对次序发生了改变,则称该算法是不稳定的

稳定的:冒泡排序,插入排序、归并排序和基数排序

不稳定的:选择排序,快速排序,希尔排序,堆排序

不稳定举例说明:

选择排序:

  —->   


快速排序:


希尔排序:

—->

堆排序:


4、使用场景:

设待排序的元素个数为n:

当n较大,则应采用时间复杂度为O(NlogN)的排序算法:快速排序,堆排序或者归并排序

  • 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短。
  • 堆排序:如果内存空间允许
  • 归并排序:内存空间允许,且要求稳定性

当n较小,可采用直接插入和选择排序

  • 直接插入排序:当元素分布有序,且要求稳定性(优先)
  • 选择排序:当元素分布有序,且不要求稳定性

一般不使用或不直接使用传统的冒泡排序。


二、算法实现


1、冒泡排序:

基本思想:

假设待排序表长为n,从前往后(或从后往前)两两比较相邻元素的值,若为逆序(即A[i]>A[i+1]),则交换他们,直到序列比较完。我们称它为一趟冒泡,会将最大的元素交换到待排序的最后一个位置。下一趟冒泡时,前一趟确定的最大元素不再参加比较,待排序列减少一个元素,每趟冒泡的结果把序列中的最大元素方法了序列的最终位置。这样最多做n-1趟冒泡就能把左右的元素排好序。

实现代码:


 
 
  1. def bubble_sort(list):
  2. for i in range(len(list) -1):
  3. for j in range(len(list)-i -1):
  4. if list[j]>list[j+ 1]:
  5. list[j+ 1],list[j] = list[j],list[j+ 1]
  6. return list
2、选择排序:

基本思想:

每一趟(例如第i趟)在后面n-i+1(i=1,2,…,n-1)个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到n-1趟做完,就不用再选了。

实现代码


 
 
  1. def select_sort(list):
  2. for i in range(len(list) -1):
  3. min = i
  4. for j in range(i+ 1,len(list)):
  5. if list[j]<list[min]:
  6. min = j
  7. list[i],list[min] = list[min],list[i]
  8. return list
3、插入排序

基本思想:

将一个记录插入到一排序好的有序表中,从而得到一个新的,记录数增1的有序表。即:现将序列的第一个记录看成是一个有序的子序列,然后从第二个记录进行插入,直至整个序列有序为止。

实现代码:


 
 
  1. def insert_sort(list):
  2. for i in range( 1,len(list)):
  3. key = list[i]
  4. for j in range(i -1, -1, -1):
  5. if list[j]>key:
  6. list[j+ 1] = list[j]
  7. list[j] = key
  8. return list
4、快速排序

基本思想:

  1. 选择一个基准元素,通常选择第一个元素或者最后一个元素
  2. 通过一趟排序将待排序的记录分割成独立的两部分,其中一部分的记录值均比基准元素小,另一部分元素值均比基准元素大
  3. 此时基准元素在其排好序后的正确位置
  4. 然后分别堆这两部分用同样的方法继续进行排序,直到整个序列有序

实现代码:


 
 
  1. def quick_sort(list,left,right):
  2. if left<right:
  3. mid = partition(list,left,right)
  4. quick_sort(list, 0,mid -1)
  5. quick_sort(list,mid+ 1,right)
  6. return list
  7. def partition(list,left,right):
  8. temp = list[left]
  9. while left<right:
  10. while left<right and list[right]>=temp:
  11. right -= 1
  12. list[left] = list[right]
  13. while left<right and list[left]<=temp:
  14. left += 1
  15. list[right] = list[left]
  16. list[left] = temp
  17. return left


5、希尔排序

希尔排序也叫缩小增量排序

基本思想:

  1. 首先取一个正数d1 = n/2,将元素分为d1个组,每组相邻元素之间的距离为d1,在各组内进行直接插入排序
  2. 取第二个正数d2 = d1 / 2,重复上述分组排序过程,直到di = 1,即所有的元素都在同一组进行直接插入排序。
  3. 希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序,最后一趟排序使得所有数据有序

实现代码:


 
 
  1. def shell_sort(list):
  2. #dk为步长
  3. dk = len(list)/ 2
  4. while dk>= 1:
  5. for i in range(dk,len(list)):
  6. temp = list[i]
  7. j = i-dk
  8. while j>= 0 and temp<list[j]:
  9. list[j+dk] = list[j]
  10. j -= dk
  11. list[j+dk] = temp
  12. dk = dk/ 2
  13. return list


6、堆排序

堆排序是一种树形选择排序方法

基本思想

  1. 建立堆
  2. 得到堆顶元素,为最大元素
  3. 去掉堆顶元素,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序
  4. 堆顶元素为第二大元素
  5. 重复步骤3,直到堆变空

实现代码:


 
 
  1. #堆排序
  2. def heap_sort(list):
  3. #初始建堆
  4. build_max_heap(list,len(list))
  5. #n-1趟的交换和建堆过程
  6. for i in range( 1,len(list))[:: -1]:
  7. #将堆顶元素list[0]和最后一个元素list[i]交换
  8. list[i],list[ 0] = list[ 0],list[i]
  9. #把剩余的i-1个元素整理成堆
  10. adjust_down(list, 0,i)
  11. return list
  12. #创建堆
  13. # n个节点的完全二叉树,最后一个节点是第n/2个节点的孩子。
  14. #对于大根堆,若根节点的关键字小于左右子女中关键字较大者,则交换,使该子树成为堆。
  15. #之后向前依次对各节点((size/2)-1~1)为根的子树进行筛选。
  16. def build_max_heap(list,size):
  17. #从size/2~1,反复调整堆。
  18. for i in range( 0,size/ 2)[:: -1]:
  19. adjust_down(list,i,size)
  20. #调整堆
  21. def adjust_down(list,i,size):
  22. max= i
  23. lchild = 2*i + 1
  24. rchild = 2*i + 2
  25. if rchild < size :
  26. if lchild < size and list[lchild] > list[max]:
  27. max = lchild
  28. if rchild < size and list[rchild] > list[max]:
  29. max = rchild
  30. if max!= i:
  31. list[max],list[i] = list[i],list[max]
  32. #继续向下调整堆
  33. adjust_down(list,max,size)


7、归并排序
基本思想:

归并排序是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列

图例:


实现代码:


 
 
  1. def merge_sort(list):
  2. if len(list)<= 1:
  3. return list
  4. mid = len(list)/ 2
  5. left = merge_sort(list[:mid])
  6. right = merge_sort(list[mid:])
  7. return merge(left,right)
  8. def merge(left,right):
  9. i,j = 0, 0
  10. #新建一个数组,用来存储将left和right排好序的值
  11. result = []
  12. while i < len(left) and j < len(right):
  13. if left[i] <= right[j]:
  14. result.append(left[i])
  15. i += 1
  16. else:
  17. result.append(right[j])
  18. j += 1
  19. result += left[i:]
  20. result += right[j:]
  21. return result




参考文献:
1、https://blog.csdn.net/lq_lq314/article/details/79183312 2018.8.6

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
1 冒泡排序: def bubble_sort(nums): for i in range(len(nums)-1): for j in range(len(nums)-i-1): if nums[j] > nums[j+1]: nums[j], nums[j+1] = nums[j+1], nums[j] return nums2. 选择排序: def selection_sort(nums): for i in range(len(nums)-1): min_idx = i for j in range(i+1, len(nums)): if nums[j] < nums[min_idx]: min_idx = j nums[i], nums[min_idx] = nums[min_idx], nums[i] return nums3. 插入排序: def insertion_sort(nums): for i in range(1, len(nums)): cur_val = nums[i] j = i - 1 while j >= 0 and nums[j] > cur_val: nums[j+1] = nums[j] j -= 1 nums[j+1] = cur_val return nums4. 希尔排序: def shell_sort(nums): gap = len(nums) // 2 while gap > 0: for i in range(gap, len(nums)): cur_val = nums[i] j = i while j >= gap and nums[j-gap] > cur_val: nums[j] = nums[j-gap] j -= gap nums[j] = cur_val gap //= 2 return nums5. 归并排序: def merge_sort(nums): if len(nums) <= 1: return nums mid = len(nums) // 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): res = [] while left_list and right_list: if left_list[0] < right_list[0]: res.append(left_list.pop(0)) else: res.append(right_list.pop(0)) res += left_list res += right_list return res6. 快速排序: def quick_sort(nums): if len(nums) <= 1: return nums pivot = nums[0] left_list = [x for x in nums[1:] if x < pivot] right_list = [x for x in nums[1:] if x >= pivot] return quick_sort(left_list) + [pivot] + quick_sort(right_list)7. 堆排序: def heap_sort(nums): n = len(nums) for i in range(n, -1, -1): heapify(nums, n, i) for i in range(n-1, 0, -1): nums[i], nums[0] = nums[0], nums[i] heapify(nums, i, 0) return numsdef heapify(nums, n, i): largest = i l = 2 * i + 1 r = 2 * i + 2 if l < n and nums[i] < nums[l]: largest = l if r < n and nums[largest] < nums[r]: largest = r if largest != i: nums[i], nums[largest] = nums[largest], nums[i] heapify(nums, n, largest)答:以上就是七大排序算法Python代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值