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的Flask框架中集成CKeditor富文本编辑器的教程
Jun 13 Python
python使用socket创建tcp服务器和客户端
Apr 12 Python
python实现音乐下载器
Apr 15 Python
深入了解Django中间件及其方法
Jul 26 Python
Python实现图片识别加翻译功能
Dec 26 Python
pycharm解决关闭flask后依旧可以访问服务的问题
Apr 03 Python
快速解决jupyter启动卡死的问题
Apr 10 Python
python如何保存文本文件
Jun 07 Python
python调用有道智云API实现文件批量翻译
Oct 10 Python
Biblibili视频投稿接口分析并以Python实现自动投稿功能
Feb 05 Python
Python OpenCV实现传统图片格式与base64转换
Jun 13 Python
Python Flask实现进度条
May 11 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
php数组去重复数据示例
2014/02/25 PHP
PHP生成不重复标识符的方法
2014/11/21 PHP
php实现微信发红包
2015/12/05 PHP
php将print_r处理后的数据还原为原始数组的解决方法
2016/11/02 PHP
php7 安装yar 生成docker镜像
2017/05/09 PHP
在Laravel5中正确设置文件权限的方法
2019/05/22 PHP
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
JS解决url传值出现中文乱码的另类办法
2013/04/08 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
js实现ifram取父窗口URL地址的方法
2015/02/09 Javascript
avalonjs实现仿微博的图片拖动特效
2015/05/06 Javascript
谈谈因Vue.js引发关于getter和setter的思考
2016/12/02 Javascript
微信小程序 仿猫眼实现实例代码
2017/03/14 Javascript
深入理解Vue transition源码分析
2017/07/30 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
JS实现HTML页面中动态显示当前时间完整示例
2018/07/30 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
jQuery.validate.js表单验证插件的使用代码详解
2018/10/22 jQuery
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
2020/02/06 Javascript
[43:47]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#2 MVP.Phx VS Fnatic第一局
2016/03/05 DOTA
Windows环境下python环境安装使用图文教程
2018/03/13 Python
基于Python3.6+splinter实现自动抢火车票
2018/09/25 Python
Django 过滤器汇总及自定义过滤器使用详解
2019/07/19 Python
Python的pygame安装教程详解
2020/02/10 Python
Python中sys模块功能与用法实例详解
2020/02/26 Python
python实现学生成绩测评系统
2020/06/22 Python
python压包的概念及实例详解
2021/02/17 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
英国第一的购买便宜玩具和游戏的在线购物网站:Bargain Max
2018/01/24 全球购物
Abbacino官网:包、钱包和女士配饰
2019/04/15 全球购物
车辆委托书范本
2014/10/05 职场文书
普通党员群众路线教育实践活动心得体会
2014/11/04 职场文书
读《工匠精神》有感:热爱工作,精益求精
2019/12/28 职场文书