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安装官方whl包和tar.gz包的方法(推荐)
Jun 04 Python
tensorflow实现softma识别MNIST
Mar 12 Python
如何使用Python的Requests包实现模拟登陆
Apr 27 Python
python hook监听事件详解
Oct 25 Python
手把手教你如何安装Pycharm(详细图文教程)
Nov 28 Python
python提取包含关键字的整行数据方法
Dec 11 Python
解决nohup执行python程序log文件写入不及时的问题
Jan 14 Python
使用Python实现跳帧截取视频帧
May 31 Python
Python中函数参数匹配模型详解
Jun 09 Python
快速解决jupyter启动卡死的问题
Apr 10 Python
pandas map(),apply(),applymap()区别解析
Feb 24 Python
Python Pandas pandas.read_sql_query函数实例用法分析
Jun 21 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之Smarty模板使用方法示例详解
2014/07/08 PHP
PHP程序员常见的40个陋习,你中了几个?
2014/11/20 PHP
js控制框架刷新
2008/08/01 Javascript
纯CSS打造的导航菜单(附jquery版)
2010/08/07 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
js中document.write的那点事
2014/12/12 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
使用jQuery操作HTML的table表格的实例解析
2016/03/13 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
2016/11/09 Javascript
微信小程序开发一键登录 获取session_key和openid实例
2016/11/23 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
解析JavaScript模仿块级作用域
2016/12/29 Javascript
Layer组件多个iframe弹出层打开与关闭及参数传递的方法
2019/09/25 Javascript
JS实现碰撞检测效果
2020/03/12 Javascript
vue通过接口直接下载java生成好的Excel表格案例
2020/10/26 Javascript
Python 变量类型及命名规则介绍
2013/06/08 Python
使用python在校内发人人网状态(人人网看状态)
2014/02/19 Python
跟老齐学Python之玩转字符串(2)
2014/09/14 Python
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
tensorflow获取变量维度信息
2018/03/10 Python
通过python爬虫赚钱的方法
2019/01/29 Python
python写入数据到csv或xlsx文件的3种方法
2019/08/23 Python
基于Django框架的权限组件rbac实例讲解
2019/08/31 Python
python实现拉普拉斯特征图降维示例
2019/11/25 Python
关于Python中定制类的比较运算实例
2019/12/19 Python
关于Pytorch的MNIST数据集的预处理详解
2020/01/10 Python
Python的pygame安装教程详解
2020/02/10 Python
DRF使用simple JWT身份验证的实现
2021/01/14 Python
美体小铺美国官网:The Body Shop美国
2017/11/10 全球购物
adidas澳大利亚官方网站:adidas Australia
2018/04/15 全球购物
工程师求职简历的自我评价分享
2013/10/10 职场文书
《二泉映月》教学反思
2014/04/15 职场文书
大学理论知识学习自我鉴定
2014/04/28 职场文书
中国梦读书活动总结
2014/07/10 职场文书
导游词之无锡唐城
2019/12/12 职场文书
Ajax实现局部刷新的方法实例
2021/03/31 Javascript