Python排序算法实例代码


Posted in Python onAugust 10, 2017

排序算法,下面算法均是使用Python实现:

插入排序

原理:循环一次就移动一次元素到数组中正确的位置,通常使用在长度较小的数组的情况以及作为其它复杂排序算法的一部分,比如mergesort或quicksort。时间复杂度为 O(n2) 。

# 1nd: 两两交换
def insertion_sort(arr):
 for i in range(1, len(arr)):
  j = i
  while j >= 0 and arr[j-1] > arr[j]:
   arr[j], arr[j-1] = arr[j-1], arr[j]
   j -= 1
 return arr
# 2nd: 交换,最后处理没交换的
def insertion_sort2(arr):
 for i in range(1, len(arr)):
  j = i-1
  key = arr[i]
  while j >= 0 and arr[j] > key:
   arr[j+1] = arr[j]
   j -= 1
  arr[j+1] = key
 return arr
# 3nd: 加速版本,利用已经排好了序的进行二分查找
def insertion_sort3(seq):
 for i in range(1, len(seq)):
  key = seq[i]
  # invariant: ``seq[:i]`` is sorted
  # find the least `low' such that ``seq[low]`` is not less then `key'.
  # Binary search in sorted sequence ``seq[low:up]``:
  low, up = 0, i
  while up > low:
   middle = (low + up) // 2
   if seq[middle] < key:
    low = middle + 1
   else:
    up = middle
  # insert key at position ``low``
  seq[:] = seq[:low] + [key] + seq[low:i] + seq[i + 1:]
 return seq
# 4nd: 原理同上,使用bisect
import bisect
def insertion_sort4(seq):
 for i in range(1, len(seq)):
  bisect.insort(seq, seq.pop(i), 0, i) # 默认插在相同元素的左边
 return seq

选择排序

原理:每一趟都选择最小的值和当前下标的值进行交换,适用在大型的数组,时间复杂度为 O(n2)

# 1nd: for
def select_sort(seq):
 for i in range(0, len(seq)):
  mi = i
  for j in range(i, len(seq)):
   if seq[j] < seq[mi]:
    mi = j
  seq[mi], seq[i] = seq[i], seq[mi]
 return seq
# 2nd: min
def select_sort2(seq):
 for i, x in enumerate(seq):
  mi = min(range(i, len(seq)), key=seq.__getitem__)
  seq[i], seq[mi] = seq[mi], x
 return seq

冒泡排序

原理:比较数组中两两相邻的数,如果第一个大于第二个,就进行交换,重复地走访过要排序的数列,达到将最小的值移动到最上面的目的,适用于小型数组,时间复杂度为O(n2)

def bubble_sort(seq):
 for i in range(len(seq)):
  for j in range(len(seq)-1-i):
   if seq[j] > seq[j+1]:
    seq[j], seq[j+1] = seq[j+1], seq[j]
 return seq
def bubble_sort2(seq):
 for i in range(0, len(seq)):
  for j in range(i + 1, len(seq)):
   if seq[i] > seq[j]:
    seq[i], seq[j] = seq[j], seq[i]
 return seq

快速排序

原理:从数组中选择pivot,分成两个数组,一个是比pivot小,一个是比pivot大,最后将这两个数组和pivot进行合并,最好情况下时间复杂度为O(n log n),最差情况下时间复杂度为O(n2)

def quick_sort(seq):
 if len(seq) >= 1:
  pivot_idx = len(seq)//2
  small, large = [], []
  for i, val in enumerate(seq):
   if i != pivot_idx:
    if val <= seq[pivot_idx]:
     small.append(val)
    else:
     large.append(val)
  quick_sort(small)
  quick_sort(large)
  return small + [seq[pivot_idx]] + large
 else:
  return seq

归并排序

原理:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

# 1nd: 将两个有序数组合并到一个数组
def merge(left, right):
 i, j = 0, 0
 result = []
 while i < len(left) and j < len(right):
  if left[i] <= right[j]:
   result.append(left[i])
   i += 1
  else:
   result.append(right[j])
   j += 1
 result += left[i:]
 result += right[j:]
 return result
def merge_sort(lists):
 if len(lists) <= 1:
  return lists
 num = len(lists) / 2
 left = merge_sort(lists[:num])
 right = merge_sort(lists[num:])
 return merge(left, right)
# 2nd: use merge
from heapq import merge
def merge_sort2(m):
 if len(m) <= 1:
  return m
 middle = len(m) // 2
 left = m[:middle]
 right = m[middle:]
 left = merge_sort(left)
 right = merge_sort(right)
 return list(merge(left, right))

堆排序

原理:堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。平均时间复杂度为O(n logn)

# 1nd: normal
def swap(seq, i, j):
 seq[i], seq[j] = seq[j], seq[i]
# 调整堆
def heapify(seq, end, i):
 l = 2 * i + 1
 r = 2 * (i + 1)
 ma = i
 if l < end and seq[i] < seq[l]:
  ma = l
 if r < end and seq[ma] < seq[r]:
  ma = r
 if ma != i:
  swap(seq, i, ma)
  heapify(seq, end, ma)
def heap_sort(seq):
 end = len(seq)
 start = end // 2 - 1
 # 创建堆
 for i in range(start, -1, -1):
  heapify(seq, end, i)
 for i in range(end - 1, 0, -1):
  swap(seq, i, 0)
  heapify(seq, i, 0)
 return seq
# 2nd: use heapq
import heapq
def heap_sort2(seq):
 """ Implementation of heap sort """
 heapq.heapify(seq)
 return [heapq.heappop(seq) for _ in range(len(seq))]

希尔排序

原理:希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

def shell_sort(seq):
 count = len(seq)
 step = 2
 group = count // step
 while group > 0:
 for i in range(0, group):
 j = i + group
 while j < count:
 k = j - group
 key = seq[j]
 while k >= 0:
  if seq[k] > key:
  seq[k + group] = seq[k]
  seq[k] = key
  k -= group
 j += group
 group //= step
 return seq

区别

Python排序算法实例代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python中使用mongoengine操作MongoDB教程
Apr 24 Python
python爬虫入门教程--利用requests构建知乎API(三)
May 25 Python
Python如何抓取天猫商品详细信息及交易记录
Feb 23 Python
Python实现的求解最大公约数算法示例
May 03 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
May 16 Python
python实现傅里叶级数展开的实现
Jul 21 Python
解决python flask中config配置管理的问题
Jul 26 Python
python系列 文件操作的代码
Oct 06 Python
解决jupyter notebook 出现In[*]的问题
Apr 13 Python
python使用Word2Vec进行情感分析解析
Jul 31 Python
Python离线安装openpyxl模块的步骤
Mar 30 Python
浅析python中特殊文件和特殊函数
Feb 24 Python
简单谈谈python中的语句和语法
Aug 10 #Python
Python中如何优雅的合并两个字典(dict)方法示例
Aug 09 #Python
Python中使用多进程来实现并行处理的方法小结
Aug 09 #Python
Python基于matplotlib绘制栈式直方图的方法示例
Aug 09 #Python
Python2.7编程中SQLite3基本操作方法示例
Aug 09 #Python
Django 前后台的数据传递的方法
Aug 08 #Python
关于python pyqt5安装失败问题的解决方法
Aug 08 #Python
You might like
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
PHP实现数组根据某个单元字段排序操作示例
2018/08/01 PHP
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
jQuery窗口、文档、网页各种高度的精确理解
2014/07/02 Javascript
浅谈javascript中基本包装类型
2015/06/03 Javascript
手机端转盘抽奖代码分享
2015/09/10 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
ReactNative-JS 调用原生方法实例代码
2016/10/08 Javascript
浅析javaScript中的浅拷贝和深拷贝
2017/02/15 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
javascript实现Java中的Map对象功能的实例详解
2017/08/21 Javascript
在knockoutjs 上自己实现的flux(实例讲解)
2017/12/18 Javascript
JavaScript复制内容到剪贴板的两种常用方法
2018/02/27 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
2019/03/29 Javascript
jquery树形插件zTree高级使用详解
2019/08/16 jQuery
vue excel上传预览和table内容下载到excel文件中
2019/12/10 Javascript
vue element ui validate 主动触发错误提示操作
2020/09/21 Javascript
详解Python中的各种函数的使用
2015/05/24 Python
python中pylint使用方法(pylint代码检查)
2018/04/06 Python
TensorFlow实现卷积神经网络
2018/05/24 Python
windows下pycharm安装、创建文件、配置默认模板
2018/07/31 Python
PyQt5实现简易电子词典
2019/06/25 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
使用 Python ssh 远程登陆服务器的最佳方案
2020/03/06 Python
PageFactory设计模式基于python实现
2020/04/14 Python
体育教育专业自荐信范文
2013/12/20 职场文书
中学生运动会入场词
2014/02/12 职场文书
企业演讲比赛主持词
2014/03/18 职场文书
婚前协议书范本
2014/04/15 职场文书
《称赞》教学反思
2016/02/17 职场文书
Css预编语言及区别详解
2021/04/25 HTML / CSS
教你怎么用python实现字符串转日期
2021/05/24 Python
实操Python爬取觅知网素材图片示例
2021/11/27 Python