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 入门教程 简单但比较不错
Nov 29 Python
Python的装饰器用法学习笔记
Jun 24 Python
Python操作Redis之设置key的过期时间实例代码
Jan 25 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
Feb 08 Python
Python读取系统文件夹内所有文件并统计数量的方法
Oct 23 Python
用python脚本24小时刷浏览器的访问量方法
Dec 07 Python
PyTorch 1.0 正式版已经发布了
Dec 13 Python
python查看文件大小和文件夹内容的方法
Jul 08 Python
python实现数据分析与建模
Jul 11 Python
使用python实现unix2dos和dos2unix命令的例子
Aug 13 Python
在Mac中配置Python虚拟环境过程解析
Jun 22 Python
python如何做代码性能分析
Apr 26 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语法(2)
2006/10/09 PHP
php防注
2007/01/15 PHP
php连接mssql的一些相关经验及注意事项
2013/02/05 PHP
zf框架的registry(注册表)使用示例
2014/03/13 PHP
yii插入数据库防并发的简单代码
2017/05/27 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
js弹窗代码 可以指定弹出间隔
2010/07/03 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
常见的jQuery选择器汇总
2014/11/24 Javascript
详解JavaScript中的blink()方法的使用
2015/06/08 Javascript
通过学习bootstrop导航条学会修改bootstrop颜色基调
2017/06/11 Javascript
vue自定义底部导航栏Tabbar的实现代码
2018/09/03 Javascript
js事件on动态绑定数据,绑定多个事件的方法
2018/09/15 Javascript
如何使用pm2快速将项目部署到远程服务器
2019/03/12 Javascript
d3.js 地铁轨道交通项目实战
2019/11/27 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
Python素数检测的方法
2015/05/11 Python
Python中线程的MQ消息队列实现以及消息队列的优点解析
2016/06/29 Python
Python中动态检测编码chardet的使用教程
2017/07/06 Python
用python打印菱形的实操方法和代码
2019/06/25 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
python破解同事的压缩包密码
2020/10/14 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
HTML5 canvas画矩形时出现边框样式不一致的解决方法
2013/10/14 HTML / CSS
AmazeUi Tree(树形结构) 应用小结
2020/08/17 HTML / CSS
adidas马来西亚官网:adidas MY
2020/09/12 全球购物
日语翻译个人求职的自我评价
2013/10/14 职场文书
综治宣传月活动总结
2014/04/28 职场文书
煤矿安全生产标语
2014/06/06 职场文书
北京奥运会主题口号
2014/06/13 职场文书
技术负责人岗位职责
2015/02/10 职场文书
小学教师师德师风自我评价
2015/03/04 职场文书
2015年大学组织委员个人工作总结
2015/10/23 职场文书
Python道路车道线检测的实现
2021/06/27 Python