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的Django框架中的ORM建立查询API
Apr 20 Python
Python实现多并发访问网站功能示例
Jun 19 Python
详解python异步编程之asyncio(百万并发)
Jul 07 Python
用Python实现读写锁的示例代码
Nov 05 Python
一篇文章搞懂Python的类与对象名称空间
Dec 10 Python
详解用Python练习画个美队盾牌
Mar 23 Python
python opencv圆、椭圆与任意多边形的绘制实例详解
Feb 06 Python
使用pandas库对csv文件进行筛选保存
May 25 Python
基于Python爬取51cto博客页面信息过程解析
Aug 25 Python
python 实现关联规则算法Apriori的示例
Sep 30 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
Oct 15 Python
用Python生成会跳舞的美女
Jan 18 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初学者们头痛的十四个问题
2007/01/15 PHP
Php Image Resize图片大小调整的函数代码
2011/01/17 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
PHP中file_exists使用中遇到的问题小结
2016/04/05 PHP
PHP基于socket实现客户端和服务端通讯功能
2017/07/13 PHP
JavaScript判断两种格式的输入日期的正确性的代码
2007/03/25 Javascript
jQuery 表单验证插件formValidation实现个性化错误提示
2009/06/23 Javascript
浅析JQuery UI Dialog的样式设置问题
2013/12/18 Javascript
js 获取、清空input type=&quot;file&quot;的值示例代码
2014/02/19 Javascript
js中的事件捕捉模型与冒泡模型实例分析
2015/01/10 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
jQuery实现动态添加tr到table的方法
2016/12/26 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
JavaScript字符串_动力节点Java学院整理
2017/06/27 Javascript
vue绑定class与行间样式style详解
2017/08/16 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
postman自定义函数实现 时间函数的思路详解
2019/04/17 Javascript
解决Layui中templet中a的onclick参数传递的问题
2019/09/20 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
微信小程序canvas开发水果老虎机的思路详解
2020/02/07 Javascript
如何在JavaScript中创建具有多个空格的字符串?
2020/02/23 Javascript
详解template标签用法(含vue中的用法总结)
2021/01/12 Vue.js
python模拟登陆阿里妈妈生成商品推广链接
2014/04/03 Python
基于Pandas读取csv文件Error的总结
2018/06/15 Python
使用k8s部署Django项目的方法步骤
2019/01/14 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
python爬虫请求头设置代码
2020/07/28 Python
使用Python Tkinter实现剪刀石头布小游戏功能
2020/10/23 Python
美国著名的婴儿学步鞋老品牌:Robeez
2016/08/20 全球购物
德国网上花店:Valentins
2018/08/15 全球购物
基层工作经历证明
2014/01/13 职场文书
护士自我鉴定总结
2014/03/24 职场文书
2014和解协议书范文
2014/09/15 职场文书
旅游投诉信范文
2015/07/02 职场文书
MySQL的prepare使用以及遇到的bug
2022/05/11 MySQL