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 相关文章推荐
Python实现简单的可逆加密程序实例
Mar 05 Python
wxPython定时器wx.Timer简单应用实例
Jun 03 Python
python实现在控制台输入密码不显示的方法
Jul 02 Python
python中解析json格式文件的方法示例
May 03 Python
Python 常用的安装Module方式汇总
May 06 Python
python实现连连看游戏
Feb 14 Python
Django操作session 的方法
Mar 09 Python
keras 获取某层输出 获取复用层的多次输出实例
May 23 Python
pycharm 关掉syntax检查操作
Jun 09 Python
Tensorflow之MNIST CNN实现并保存、加载模型
Jun 17 Python
Python使用itcaht库实现微信自动收发消息功能
Jul 13 Python
Python识别验证码的实现示例
Sep 30 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转盘抽奖接口实例
2015/02/09 PHP
Yii2 ActiveRecord多表关联及多表关联搜索的实现
2016/06/30 PHP
CI框架中类的自动加载问题分析
2016/11/21 PHP
彻底搞懂PHP 变量结构体
2017/10/11 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
JavaScript delete 属性的使用
2009/10/08 Javascript
js判断变量是否未定义的代码
2020/03/28 Javascript
动态加载JS文件的三种方法
2013/11/08 Javascript
jQuery制作效果超棒的手风琴折叠菜单
2015/04/03 Javascript
浅谈javascript中的闭包
2015/05/13 Javascript
thinkjs之页面跳转同步异步操作
2017/02/05 Javascript
解决微信二次分享不显示摘要和图片的问题
2017/08/18 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
原生javascript制作贪吃蛇小游戏的方法分析
2020/02/26 Javascript
JavaScript实现图片伪异步上传过程解析
2020/04/10 Javascript
微信小程序点击滚动到指定位置的实现
2020/05/22 Javascript
在Windows8上的搭建Python和Django环境
2014/07/03 Python
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
2015/03/19 Python
python对象及面向对象技术详解
2016/07/19 Python
Python实现的异步代理爬虫及代理池
2017/03/17 Python
pyqt5 删除layout中的所有widget方法
2019/06/25 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
浅谈Python中函数的定义及其调用方法
2019/07/19 Python
html5默认气泡修改的代码详解
2020/03/13 HTML / CSS
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
Ibatis中如何提高SQL Map的性能
2013/05/11 面试题
UNIX文件类型
2013/08/29 面试题
《雪儿》教学反思
2014/04/17 职场文书
优秀教师申报材料
2014/12/16 职场文书
结婚典礼致辞
2015/07/28 职场文书
学校教师培训工作总结
2015/10/14 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
Java tomcat手动配置servlet详解
2021/11/27 Java/Android
mysql 索引的数据结构为什么要采用B+树
2022/04/26 MySQL
Android中View.post和Handler.post的关系
2022/06/05 Java/Android
分享很少见很有用的SQL功能CORRESPONDING
2022/08/05 MySQL