10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
作者:沙振宇 发布时间:2021-05-21 05:28:13
我简单的绘制了一下排序算法的分类,蓝色字体的排序算法是我们用python3实现的,也是比较常用的排序算法。
Python3常用排序算法
1、Python3冒泡排序——交换类排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
作为最简单的排序算法之一,冒泡排序给我的感觉就像Abandon在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。
冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。
但这种改进对于提升性能来说并没有什么太大作用。
最快:当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊)
最慢:当输入的数据是反序时(写一个 for 循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)
Python3冒泡排序实例代码
# 冒泡排序
def bubbleSort(arr):
for i in range(1, len(arr)):
for j in range(0, len(arr)-i):
if arr[j] > arr[j+1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = bubbleSort(list)
print("List sort is:", result)
效果
2、Python3快速排序-交换类排序
快速排序是由东尼·霍尔所发展的一种排序算法。
在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。
特点:选基准、分治、递归
Python3快速排序-交换类排序实例源码
# 快速排序
def quickSort(arr, left=None, right=None):
left = 0 if not isinstance(left,(int, float)) else left
right = len(arr)-1 if not isinstance(right,(int, float)) else right
if left < right:
partitionIndex = partition(arr, left, right)
quickSort(arr, left, partitionIndex-1)
quickSort(arr, partitionIndex+1, right)
return arr
def partition(arr, left, right):
pivot = left
index = pivot+1
i = index
while i <= right:
if arr[i] < arr[pivot]:
swap(arr, i, index)
index+=1
i+=1
swap(arr,pivot,index-1)
return index-1
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = quickSort(list)
print("List sort is:", result)
Python3快排简写
def quickSort2(array):
return array if len(array) <= 1 else quickSort2([lt for lt in array[1:] if lt < array[0]]) + array[0:1] + quickSort2([ge for ge in array[1:] if ge >= array[0]])
效果
3、Python3选择排序-选择类排序
选择排序是一种简单直观的排序算法。
无论什么数据进去都是 O(n2) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
Python3选择排序-选择类排序实例源码
# 选择排序
def selectionSort(arr):
for i in range(len(arr) - 1):
# 记录最小数的索引
minIndex = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[minIndex]:
minIndex = j
# i 不是最小数时,将 i 和最小数进行交换
if i != minIndex:
arr[i], arr[minIndex] = arr[minIndex], arr[i]
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = selectionSort(list)
print("List sort is:", result)
效果
4、Python3堆排序-选择类排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。
堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
1、大顶堆(大根堆):每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
2、小顶堆(小根堆):每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
堆排序的平均时间复杂度为 Ο(nlogn)。
Python3堆排序-选择类排序实例源码
# 堆排序
def buildMaxHeap(arr):
import math
for i in range(math.floor(len(arr)/2),-1,-1):
heapify(arr,i)
def heapify(arr, i):
left = 2*i+1
right = 2*i+2
largest = i
if left < arrLen and arr[left] > arr[largest]:
largest = left
if right < arrLen and arr[right] > arr[largest]:
largest = right
if largest != i:
swap(arr, i, largest)
heapify(arr, largest)
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def heapSort(arr):
global arrLen
arrLen = len(arr)
buildMaxHeap(arr)
for i in range(len(arr)-1,0,-1):
swap(arr,0,i)
arrLen -=1
heapify(arr, 0)
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = heapSort(list)
print("List sort is:", result)
效果
5、Python3插入排序-插入类排序
插入排序是一种最简单直观的排序算法。
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
Python3插入排序-插入类排序实例源码
# 作者:沙振宇
# 插入排序
def insertionSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = insertionSort(list)
print("List sort is:", result)
效果
6、Python3希尔排序-插入类排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。
但希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
1、插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
2、但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
希尔排序的基本思想是:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
Python3希尔排序-插入类排序实例源码
# 作者:沙振宇
# 希尔排序
def shellSort(arr):
import math
gap=1
while(gap < len(arr)/3):
gap = gap*3+1
while gap > 0:
for i in range(gap,len(arr)):
temp = arr[i]
j = i-gap
while j >=0 and arr[j] > temp:
arr[j+gap]=arr[j]
j-=gap
arr[j+gap] = temp
gap = math.floor(gap/3)
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = shellSort(list)
print("List sort is:", result)
效果
7、Python3归并排序-归并类排序
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
1、自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
2、自下而上的迭代;
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间
Python3归并排序-归并类排序实例源码
# 作者:沙振宇
# 归并排序
def mergeSort(arr):
import math
if(len(arr)<2):
return arr
middle = math.floor(len(arr)/2)
left, right = arr[0:middle], arr[middle:]
return merge(mergeSort(left), mergeSort(right))
def merge(left,right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return result
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = mergeSort(list)
print("List sort is:", result)
效果
8、Python3计数排序-分布类排序
计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。
作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。
由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。
通俗地理解,例如有 10 个年龄不同的人,统计出有 8 个人的年龄比 A 小,那 A 的年龄就排在第 9 位,用这个方法可以得到其他每个人的位置,也就排好了序。当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去 1 的原因。
Python3计数排序-分布类排序实例源码
# 作者:沙振宇
# 计数排序
def countingSort(arr, maxValue):
bucketLen = maxValue+1
bucket = [0]*bucketLen
sortedIndex =0
arrLen = len(arr)
for i in range(arrLen):
if not bucket[arr[i]]:
bucket[arr[i]]=0
bucket[arr[i]]+=1
for j in range(bucketLen):
while bucket[j]>0:
arr[sortedIndex] = j
sortedIndex+=1
bucket[j]-=1
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = countingSort(list,max(list))
print("List sort is:", result)
效果
9、Python3基数排序-分布类排序
基数排序是一种非比较型整数排序算法。
其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
python3基数排序-分布类排序实例源码
# 作者:沙振宇
# 基数排序
def radix_sort(arr):
"""基数排序"""
i = 0 # 记录当前正在排拿一位,最低位为1
max_num = max(arr) # 最大值
j = len(str(max_num)) # 记录最大值的位数
while i < j:
bucket_list =[[] for _ in range(10)] #初始化桶数组
for x in arr:
bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶数组
arr.clear()
for x in bucket_list: # 放回原序列
for y in x:
arr.append(y)
i += 1
return arr
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = radix_sort(list)
print("List sort is:", result)
效果
Python3桶排序-分布类排序
桶排序是计数排序的升级版。
它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:
1、在额外空间充足的情况下,尽量增大桶的数量
2、使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
最快:当输入的数据可以均匀的分配到每一个桶中。
最慢:当输入的数据被分配到了同一个桶中。
Python3桶排序-分布类排序实例源码
# 作者:沙振宇
# 桶排序
def bucketSort(arr):
# 选择一个最大的数
max_num = max(arr)
# 创建一个元素全是0的列表, 当做桶
bucket = [0] * (max_num + 1)
# 把所有元素放入桶中, 即把对应元素个数加一
for i in arr:
bucket[i] += 1
# 存储排序好的元素
sort_nums = []
# 取出桶中的元素
for j in range(len(bucket)):
if bucket[j] != 0:
for y in range(bucket[j]):
sort_nums.append(j)
return sort_nums
if __name__ == '__main__':
list = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
print("List source is:", list)
result = bucketSort(list)
print("List sort is:", result)
效果
本文主要讲解了10个python3常用排序算法详细说明与实例,更多关于python排序算法的知识请查看下面的相关链接
来源:https://blog.csdn.net/u014597198/article/details/91395700


猜你喜欢
- 题目描述利用opencv或其他工具编写程序实现缺陷检测。实现过程# -*- coding: utf-8 -*-'''
- 让我们重温一下JavaScript的一些基础知识,请先写出以下代码中问号处的答案,再运行比较!<script type=&q
- 本文实例讲述了Python数据结构与算法之常见的分配排序法。分享给大家供大家参考,具体如下:箱排序(桶排序)箱排序是根据关键字的取值范围1~
- 文件名称:ByVal.aspByRef.asp具体代码:<%Sub TestMain()Dim A : A=5Call TestBy(
- asp使用WScript.Shell获取电脑的网络配置信息Option Explicit Dim WSHShe
- jqGrid是一个优秀的基于jQuery的DataGrid框架,想必大伙儿也不陌生,网上基于ASP的资料很少,我提供一个,数据格式是json
- 一、脚本说明1、linux系统版本EL6, EL7, EL8, and EL9-based platforms (for example,
- 前言提示:这里可以添加本文要记录的大概内容:公司里B2B是通过WinSCP里SFTP与客户进行数据传输,WinSCP是一个Windows环境
- 现在不写asp了这次我将我以前沉淀下的一些函数库共享给大家,希望能给初学者启示,给老手也有所帮助吧.先谢谢大家支持! <%@
- 问题说明最近在写爬虫,由于单个账号访问频率太高会被封,所以需要在爬虫执行一段时间间隔后自己循环切换账号所以就在想,有没有像单片机那样子设置一
- 对于网站设计者而言,时常处理大批量的文件是难免的,特别是图片和一些文本文本文件,更是经常处理。而由于网站大量文件的关系,对于同类
- 简述:Django的admin可以提供一个强大的后台管理功能,可以在web界面对数据库进行操作,我们需要修改admin.py将要操作的数据表
- 整个安装流程如下: 1,首先安装apache:我安装的版本是: httpd-2.2.16-win32-x86-openssl-0.9.8o.
- 在炼丹时,数据的读取与预处理是关键一步。不同的模型所需要的数据以及预处理方式各不相同,如果每个轮子都我们自己写的话,是很浪费时间和精力的。P
- 错误号 错误信息5 &n
- 用pycharm和pyqt5,想写一个弹出窗口的程序,如下:class video_record(QWidget): &nbs
- 前言Windows10 在 UWP 应用中支持亚克力画刷,可以在部件的底部绘制亚克力效果的背景图。下面我们使用 QLabel 来模拟这个磨砂
- 前言一直想好好学习一下Python爬虫,之前断断续续的把Python基础学了一下,悲剧的是学的没有忘的快。只能再次拿出来滤了一遍,趁热打铁,
- 背景作为一门相对新兴的语言,Go 可以说是站在巨人的肩膀上。从 Go 语法上,我们可以看出设计者对其有许多严肃的思考。其中 Error 的处
- 背景一直对语音合成系统比较感兴趣,总想能给自己合成一点内容,比如说合成小说,把我下载的电子书播报给我听等等。语音合成系统其实就是一个基于语音