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显示天气预报
Mar 02 Python
python用10行代码实现对黄色图片的检测功能
Aug 10 Python
使用Python抓取豆瓣影评数据的方法
Oct 17 Python
利用Python将文本中的中英文分离方法
Oct 31 Python
python reverse反转部分数组的实例
Dec 13 Python
Tensorflow 卷积的梯度反向传播过程
Feb 10 Python
40行Python代码实现天气预报和每日鸡汤推送功能
Feb 27 Python
Python实现对adb命令封装
Mar 06 Python
python列表删除和多重循环退出原理详解
Mar 26 Python
Django实现列表页商品数据返回教程
Apr 03 Python
python实现与redis交互操作详解
Apr 21 Python
深入浅析python3 依赖倒置原则(示例代码)
Jul 09 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
水质对咖图啡风味的影响具体有哪些
2021/03/03 冲泡冲煮
PHP中的加密功能
2006/10/09 PHP
ajax php 实现写入数据库
2009/09/02 PHP
Prototype ObjectRange对象学习
2009/07/19 Javascript
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
js实现拖拽效果
2015/02/12 Javascript
js钢琴按钮波浪式图片排列效果代码分享
2015/08/26 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
JavaScript的设计模式经典之代理模式
2016/02/24 Javascript
require.js配合插件text.js实现最简单的单页应用程序
2016/07/12 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
2016/12/12 Javascript
JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例
2018/02/08 Javascript
Vue-路由导航菜单栏的高亮设置方法
2018/03/17 Javascript
动态加载JavaScript文件的3种方式
2018/05/05 Javascript
基于Vue实现平滑过渡的拖拽排序功能
2019/06/12 Javascript
Vue中多元素过渡特效的解决方案
2020/02/05 Javascript
Vue向后台传数组数据,springboot接收vue传的数组数据实例
2020/11/12 Javascript
[01:01:41]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第二场 1月31日
2021/03/11 DOTA
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
Python加密模块的hashlib,hmac模块使用解析
2020/01/02 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
python实现俄罗斯方块游戏(改进版)
2020/03/13 Python
python实现b站直播自动发送弹幕功能
2021/02/20 Python
南非领先的在线旅行社:Travelstart南非
2016/09/04 全球购物
Java基础类库面试题
2013/09/04 面试题
护理专业推荐信
2013/11/07 职场文书
财务部出纳岗位职责
2013/12/22 职场文书
领导干部廉政自律承诺书
2014/05/26 职场文书
大学生撤销处分思想汇报
2014/09/12 职场文书
小学生运动会报道稿
2014/09/12 职场文书
党委书记群众路线对照检查材料思想汇报
2014/10/04 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
2014年客服工作总结与计划
2014/12/09 职场文书
小学生思想品德评语
2014/12/31 职场文书
检讨书模板大全
2015/05/07 职场文书