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中datetime常用时间处理方法
Jun 15 Python
基于Python Shell获取hostname和fqdn释疑
Jan 25 Python
Python处理JSON时的值报错及编码报错的两则解决实录
Jun 26 Python
Python编程生成随机用户名及密码的方法示例
May 05 Python
Python实现的文本简单可逆加密算法示例
May 18 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
Dec 21 Python
Pytorch中的VGG实现修改最后一层FC
Jan 15 Python
Python异常继承关系和自定义异常实现代码实例
Feb 20 Python
django项目中新增app的2种实现方法
Apr 01 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
Apr 26 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
Python实现提取PDF简历信息并存入Excel
Apr 02 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伪造referer的方法 利用referer防止图片盗链
2014/01/20 PHP
详解php curl带有csrf-token验证模拟提交方法
2018/04/18 PHP
PHP的JSON封装、转变及输出操作示例
2019/09/27 PHP
PHP $O00OO0=urldecode &amp; eval 解密,记一次商业源码的去后门
2020/09/13 PHP
Javascript 强制类型转换函数
2009/05/17 Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
2010/07/29 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
使用js写的一个简易的投票
2013/11/27 Javascript
根据当前时间在jsp页面上显示上午或下午
2014/08/18 Javascript
jquery实现动态改变div宽度和高度
2015/05/08 Javascript
jquery中toggle函数交替使用问题
2015/06/22 Javascript
JavaScript 函数的执行过程
2016/05/09 Javascript
教你用Cordova打包Vue项目的方法
2017/10/17 Javascript
浅谈vant组件Picker 选择器选单选问题
2020/11/04 Javascript
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
python实现计算资源图标crc值的方法
2014/10/05 Python
python函数装饰器用法实例详解
2015/06/04 Python
Python使用PyCrypto实现AES加密功能示例
2017/05/22 Python
python 将列表中的字符串连接成一个长路径的方法
2018/10/23 Python
浅析PyTorch中nn.Module的使用
2019/08/18 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
CSS3属性 line-clamp控制文本行数的使用
2020/03/19 HTML / CSS
浅析HTML5中header标签的用法
2016/06/24 HTML / CSS
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
Reebok官方旗舰店:美国知名健身品牌锐步
2019/01/07 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
服装销售人员求职自我评价
2013/09/26 职场文书
旅游管理本科生求职信
2013/10/14 职场文书
医院实习接收函
2014/01/12 职场文书
大学国际贸易专业自荐信
2014/06/05 职场文书
学校地质灾害防治方案
2014/06/10 职场文书
羽毛球比赛策划方案
2014/06/13 职场文书
学校教师安全责任书
2014/07/23 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书
IIS服务器中设置HTTP重定向访问HTTPS
2022/04/29 Servers