十大经典排序算法的python实现
十种常见排序算法可以分为两大类:
非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。包括:冒泡排序、选择排序、归并排序、快速排序、插入排序、希尔排序、堆排序等。
线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。包括:计数排序、桶排序、基数排序等。
下面介绍各种算法的基本思想及python实现:
1 冒泡排序(Bubble Sort)
1.1 基本思想:
它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
1.2 实现代码:
def bubbleSort(arr):
n = len(arr)
for i in range(n-1):
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
2 选择排序(Selection Sort)
2.1 基本思想:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
2.2 实现代码
def selectionSort(arr):
n = len(arr)
for i in range(n-1):
minIndex = i
for j in range(i+1, n, 1):
if arr[j] < arr[minIndex]:
minIndex = j
arr[i], arr[minIndex] = arr[minIndex], arr[i]
return arr
3 插入排序(Insertion Sort)
3.1 基本思想
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
3.2 实现代码
def insertionSort(arr):
n = len(arr)
for i in range(1, n):
for j in range(i, 0, -1):
if arr[j] < arr[j-1]:
arr[j-1], arr[j] = arr[j], arr[j-1]
return arr
4 希尔排序(Shell Sort)
4.1 基本思想
它是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素,将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序。希尔排序又叫缩小增量排序。
4.2 实现代码
def shellsort(arr):
n = len(arr)
group = 3
gap = n // group
while gap > 0:
for i in range(0, gap):
for j in range(i+gap, n, gap):
tmp = arr[j]
for k in range(j-gap, i-1, -gap):
if arr[k] >= arr[j]:
arr[k + gap], arr[k] = arr[k], tmp
gap //= group
return arr
5 归并排序(Merge Sort)
5.1 基本思想
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
5.2 实现代码
def mergeSort(arr):
if len(arr) < 2:
return arr
middle = int(len(arr) / 2)
left = mergeSort(arr[:middle])
right = mergeSort(arr[middle:])
return merge(left, right)
def merge(left, right):
result = []
leftindex = rightindex = 0
while leftindex < len(left) and rightindex < len(right):
if left[leftindex] <= right[rightindex]:
result.append(left[leftindex])
leftindex += 1
else:
result.append(right[rightindex])
rightindex += 1
if len(left):
for i in left[leftindex:]:
result.append(i)
if len(right):
for i in right[rightindex:]:
result.append(i)
return result
6 快速排序(Quick Sort)
6.1 基本思想
通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
6.2 实现代码
def quickSort(arr, left, 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 = right
i = left - 1
for j in range(left, right):
if arr[j] <= arr[pivot]:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[pivot] = arr[pivot], arr[i+1]
# print(arr)
return i + 1
7 堆排序(Heap Sort)
7.1 基本思想
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
7.2 代码实现
def adjust_heap(arr, i, n):
lchild = 2 * i + 1
rchild = 2 * i + 2
max = i
if i < n / 2:
if lchild < n and arr[lchild] > arr[max]:
max = lchild
if rchild < n and arr[rchild] > arr[max]:
max = rchild
if max != i:
arr[max], arr[i] = arr[i], arr[max]
adjust_heap(arr, max, n) # 下滤
def build_max_heap(arr, n):
for i in range(0, int(n // 2))[::-1]:
adjust_heap(arr, i, n)
def heap_sort(arr):
n = len(arr)
build_max_heap(arr, n)
for i in range(0, n)[::-1]:
arr[0], arr[i] = arr[i], arr[0]
adjust_heap(arr, 0, i) # 下滤
return arr
8 计数排序
8.1 基本思想
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
8.2 实现代码
def countingSort(arr, maxValue):
bucket = np.array(np.zeros(maxValue + 1)) # 算上0,arr必须是正数
sortedIndex = 0
bucketLen = maxValue + 1
n = len(arr)
for i in range(0, n):
# if bucket[arr[i]]:
bucket[arr[i]] += 1
for j in range(0, bucketLen):
while bucket[j] > 0:
arr[sortedIndex] = j
sortedIndex += 1
bucket[j] -= 1
return arr
9 桶排序
9.1 基本思想
假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(可以使用别的排序算法或是以递归方式继续使用桶排序进行排)。
9.2 实现代码
def bucketSort(arr, bucketSize):
if len(arr) == 0:
return arr
minValue = min(arr) # 输入数据的最小值
maxValue = max(arr) # 输入数据的最大值
# 桶的初始化
DEFAULT_BUCKET_SIZE = 5 # 设置桶的默认数量为5
bucketSize = bucketSize | DEFAULT_BUCKET_SIZE # 按照位或(二进制)
bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
buckets = [[] for i in range(bucketCount)] # 利用映射函数将数据分配到各个桶中
for i in range(0, len(arr)):
(buckets[math.floor((arr[i] - minValue) / bucketSize)]).append(arr[i])
arr = []
for i in range(0, len(buckets)):
insertionSort(buckets[i]) # 对每个桶进行排序,这里使用了插入排序
for j in range(0, len(buckets[i])):
arr.append(buckets[i][j])
return arr
10 基数排序
10.1 基本思想
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
10.2 实现代码
import math
def radix_sort(arr, radix=10):
k = int(math.ceil(math.log(max(arr), radix))) # 取得位数
bucket = [[] for i in range(radix)] # 初始化 bucket = [[],[],...]
for i in range(1, k+1):
for j in arr:
bucket[j % (radix ** i) // (radix ** (i - 1))].append(j) # 先截取元素的后k位数再取第k位上的数字(k=1,2...)
del arr[:]
for z in bucket:
arr += z
print(arr)
del z[:]
return arr
参考:https://www.cnblogs.com/onepixel/articles/7674659.html
十大经典排序算法的python实现的更多相关文章
- 十大经典排序算法(python实现)(原创)
个人最喜欢的排序方法是非比较类的计数排序,简单粗暴.专治花里胡哨!!! 使用场景: 1,空间复杂度 越低越好.n值较大: 堆排序 O(nlog2n) O(1) 2,无空间复杂度要求.n值较大: 桶排序 ...
- 十大经典排序算法总结 (Python)
作业部落:https://www.zybuluo.com/listenviolet/note/1399285 以上链接是自己在作业部落编辑的排序算法总结- Github: https://github ...
- python实现十大经典排序算法
Python实现十大经典排序算法 代码最后面会给出完整版,或者可以从我的Githubfork,想看动图的同学可以去这里看看: 小结: 运行方式,将最后面的代码copy出去,直接python sort. ...
- 用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并等
本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序.选择排序.快速排序.冒泡排序.归并排序.希尔排序.插入排序.桶排序.基数排序.计数排序算法,想要学习的你们,继续阅读下去吧,如 ...
- 十大经典排序算法最强总结(含Java、Python码实现)
引言 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面 ...
- python基础__十大经典排序算法
用Python实现十大经典排序算法! 排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大, ...
- 十大经典排序算法+sort排序
本文转自:十大经典排序算法,其中有动图+代码详解,本文简单介绍+个人理解. 排序算法 经典的算法问题,也是面试过程中经常被问到的问题.排序算法简单分类如下: 这些排序算法的时间复杂度等参数如下: 其中 ...
- 十大经典排序算法的 JavaScript 实现
计算机领域的都多少掌握一点算法知识,其中排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大 ...
- JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)
1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...
随机推荐
- zookeeper实现动态感知服务器上下线
在实际的生产环境中我们一般都是集群环境部署的,同一个程序我们会部署在相同的几台服务器中,这时我们可以通过负载均衡服务器去调度,但是我们并不能很快速的获知哪台服务器挂掉了,这时我们就可以使用zook ...
- Linux上磁盘热插拔
首先获取scsi设备的信息. [root@server2 ~]# lsscsi [:::] disk VMware, VMware Virtual S 1.0 /dev/sda [:::] cd/dv ...
- 应用负载均衡之LVS(三):ipvsadm命令
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- Perl文件句柄相关常量变量
文件句柄相关变量 对应的官方手册:http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles 默认情况下: $/:输入行 ...
- 分布式系统监视zabbix讲解四之可视化--技术流ken
图形 概述 随着大量的监控数据被采集到Zabbix中,如果用户可以以可视化的表现形式来查看发生了什么事情,那么和仅仅只有数字的表现形式比起来则更加轻松. 以下是进行图形设置的地方.图形可以一目了然地掌 ...
- 用python实现红包机制
方法一,逻辑是后一个红包的范围是[0.01,剩下的钱*2/剩下的红包数,如果最后钱不足分配给每个人,就把后几个每人分配0.01元. 主要思想就是,每个人至少能领取到0.01元. import rand ...
- [android] 保存文件到SD卡
/****************2016年5月4日 更新*****************************/ 知乎:为什么很多Android应用要把文件写到/sdcard目录下而不是写到/d ...
- jdk的配置(适用于win7、win8、win10)
一.前言 win7和win8的jdk配置基本一样,所以本文以win7和win10来说明配置. 二.win7jdk环境配置(win8和这个一样) 首先安装好jdk,这里已安装好jdk7,本文采取的是jd ...
- springboot最新版本自定义日志注解和AOP
LogAspectAnnotation @ControllerLogAspectAnnotation /** * * Define a log facet annotation * @author s ...
- Spring Cloud 研发框架demo
第一步:准备工作 1.下载并集成公司自定义maven maven包见QQ群文件 2.克隆Git源码到本地eclipse: xx 3.构建项目 一键初始化parent:run as maven inst ...