python 常见的排序算法实现汇总


Posted in Python onAugust 21, 2020

python 常见的排序算法实现汇总

排序分为两类,比较类排序和非比较类排序,比较类排序通过比较来决定元素间的相对次序,其时间复杂度不能突破O(nlogn);非比较类排序可以突破基于比较排序的时间下界,缺点就是一般只能用于整型相关的数据类型,需要辅助的额外空间。

要求能够手写时间复杂度位O(nlogn)的排序算法:快速排序、归并排序、堆排序

1.冒泡排序

思想:相邻的两个数字进行比较,大的向下沉,最后一个元素是最大的。列表右边先有序。

时间复杂度$O(n^2)$,原地排序,稳定的

def bubble_sort(li:list):
  for i in range(len(li)-1):
    for j in range(i + 1, len(li)):
      if li[i] > li[j]:
        li[i], li[j] = li[j], li[i]

2.选择排序

思想:首先找到最小元素,放到排序序列的起始位置,然后再从剩余元素中继续寻找最小元素,放到已排序序列的末尾,以此类推,直到所有元素均排序完毕。列表左边先有序。

时间复杂度$O(n^2)$,原地排序,不稳定

def select_sort(nums: list):
  for i in range(len(nums) - 1):
    min_index = i
    for j in range(i + 1, len(nums)):
      if nums[j] < nums[i]:
        min_index = j
    nums[i], nums[min_index] = nums[min_index], nums[i]

3.插入排序

思想:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。列表左边先有序。

时间复杂度$O(n^2)$,原地排序,稳定

def insert_sort(nums: list):
  for i in range(len(nums)):
    current = nums[i]
    pre_index = i - 1
    while pre_index >= 0 and nums[pre_index] > current:
      nums[pre_index + 1] = nums[pre_index]
      pre_index -= 1
    nums[pre_index + 1] = current

4.希尔排序

思想:插入排序的改进版,又称缩小增量排序,将待排序的列表按下标的一定增量分组,每组分别进行直接插入排序,增量逐渐减小,直到为1,排序完成

时间复杂度$O(n^{1.5})$,原地排序,不稳定

def shell_sort(nums: list):
  gap = len(nums) >> 1
  while gap > 0:
    for i in range(gap, len(nums)):
      current = nums[i]
      pre_index = i - gap
      while pre_index >= 0 and nums[pre_index] > current:
        nums[pre_index + gap] = nums[pre_index]
        pre_index -= gap
      nums[pre_index + gap] = current
    gap >>= 1

5.快速排序

思想:递归,列表中取出第一个元素,作为标准,把比第一个元素小的都放在左侧,把比第一个元素大的都放在右侧,递归完成时就是排序结束的时候

时间复杂度$O(nlogn)$,空间复杂度$O(logn)$,不稳定

def quick_sort(li:list):
  if li == []:
    return []
  first = li[0]
  # 推导式实现
  left = quick_sort([l for l in li[1:] if l < first])
  right = quick_sort([r for r in li[1:] if r >= first])
  return left + [first] + right

6.归并排序

思想:分治算法,拆分成子序列,使用归并排序,将排序好的子序列合并成一个最终的排序序列。关键在于怎么合并:设定两个指针,最初位置分别为两个已经排序序列的起始位置,比较两个指针所指向的元素,选择相对小的元素放到合并空间,并将该指针移到下一位置,直到某一指针超出序列尾,将另一序列所剩下的所有元素直接复制到合并序列尾。

时间复杂度$O(nlogn)$,空间复杂度O(n),不稳定

二路归并

def merge_sort(nums: list):
  if len(nums) <= 1:
    return nums
  mid = len(nums) >> 1
  left = merge_sort(nums[:mid]) # 拆分子问题
  right = merge_sort(nums[mid:])

  def merge(left, right): # 如何归并
    res = []
    l, r = 0, 0
    while l < len(left) and r < len(right):
      if left[l] <= right[r]:
        res.append(left[l])
        l += 1
      else:
        res.append(right[r])
        r += 1
    res += left[l:]
    res += right[r:]
    return res

  return merge(left, right)

7.堆排序

思想:根节点最大,大顶堆,对应升序,根节点最小,小顶堆。

  • 构建大根堆,完全二叉树结构,初始无序
  • 最大堆调整,进行堆排序。将堆顶元素与最后一个元素交换,此时后面有序

时间复杂度$O(nlogn)$,原地排序,稳定

def heap_sort(nums: list):
  def heapify(parent_index, length, nums):
    temp = nums[parent_index] # 根节点的值
    chile_index = 2 * parent_index + 1 # 左节点,再加一为右节点
    while chile_index < length:
      if chile_index + 1 < length and nums[chile_index + 1] > nums[chile_index]:
        chile_index = chile_index + 1
      if temp > nums[chile_index]:
        break
      nums[parent_index] = nums[chile_index] # 使得根节点最大
      parent_index = chile_index
      chile_index = 2 * parent_index + 1
    nums[parent_index] = temp

  for i in range((len(nums) - 2) >> 1, -1, -1):
    heapify(i, len(nums), nums) # 1.建立大根堆
  for j in range(len(nums) - 1, 0, -1):
    nums[j], nums[0] = nums[0], nums[j]
    heapify(0, j, nums) # 2.堆排序,为升序
    
if __name__ == '__main__':
  nums = [89, 3, 3, 2, 5, 45, 33, 67] # [2, 3, 3, 5, 33, 45, 67, 89]
  heap_sort(nums)
  print(nums)

以上就是python 常见的排序算法实现汇总的详细内容,更多关于python 排序算法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python3读取zip文件信息的方法
May 22 Python
浅谈Python中列表生成式和生成器的区别
Aug 03 Python
Python科学计算之NumPy入门教程
Jan 15 Python
python编程羊车门问题代码示例
Oct 25 Python
tensorflow获取变量维度信息
Mar 10 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
Jul 14 Python
Django 过滤器汇总及自定义过滤器使用详解
Jul 19 Python
Pytorch 神经网络—自定义数据集上实现教程
Jan 07 Python
Tensorflow 多线程设置方式
Feb 06 Python
Python小白垃圾回收机制入门
Jun 09 Python
用Python开发app后端有优势吗
Jun 29 Python
Sentry错误日志监控使用方法解析
Nov 12 Python
Python制作数据预测集成工具(值得收藏)
Aug 21 #Python
简述 Python 的类和对象
Aug 21 #Python
DRF框架API版本管理实现方法解析
Aug 21 #Python
Django rest framework分页接口实现原理解析
Aug 21 #Python
Python -m参数原理及使用方法解析
Aug 21 #Python
python使用布隆过滤器的实现示例
Aug 20 #Python
QT5 Designer 打不开的问题及解决方法
Aug 20 #Python
You might like
深入php define()函数以及defined()函数的用法详解
2013/06/05 PHP
PHP通过API获取手机号码归属地
2015/05/28 PHP
老生常谈PHP面向对象之注册表模式
2017/05/26 PHP
php中curl和soap方式请求服务超时问题的解决
2018/06/11 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
再探JavaScript作用域
2014/09/24 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
2015/09/17 Javascript
页面内容排序插件jSort使用方法
2015/10/10 Javascript
深入解析AngularJS框架中$scope的作用与生命周期
2016/03/05 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
详解Angular开发中的登陆与身份验证
2016/07/27 Javascript
使用travis-ci如何持续部署node.js应用详解
2017/07/30 Javascript
浅谈ajax请求不同页面的微信JSSDK问题
2018/02/26 Javascript
基于Vue组件化的日期联动选择器功能的实现代码
2018/11/30 Javascript
JS实现马赛克图片效果完整示例
2019/04/13 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
在VUE style中使用data中的变量的方法
2020/06/19 Javascript
解决vue-router 切换tab标签关闭时缓存问题
2020/07/22 Javascript
python文件名和文件路径操作实例
2017/09/29 Python
对Python中DataFrame选择某列值为XX的行实例详解
2019/01/29 Python
django框架基于模板 生成 excel(xls) 文件操作示例
2019/06/19 Python
获取django框架orm query执行的sql语句实现方法分析
2019/06/20 Python
django model的update时auto_now不被更新的原因及解决方式
2020/04/01 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
html5弹跳球示例代码
2013/07/23 HTML / CSS
HTML5 Canvas+JS控制电脑或手机上的摄像头实例
2014/05/03 HTML / CSS
美国知名女性服饰品牌:New York & Company
2017/03/23 全球购物
经销商会议欢迎词
2014/01/11 职场文书
银行开业庆典方案
2014/02/06 职场文书
中学生演讲稿
2014/04/26 职场文书
宣传标语大全
2014/07/01 职场文书
材料化学专业求职信
2014/07/15 职场文书
2014年工作总结与下年工作计划
2014/11/27 职场文书
大学军训通讯稿
2015/07/18 职场文书
2016大学生社会实践单位评语
2015/12/01 职场文书