十大经典排序算法的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 数据结构与算法之美 系列用的语言是 ...
随机推荐
- Hibernate学习(八)———— Hibernate检索策略(类级别,关联级别,批量检索)详解
序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要 ...
- go基础系列:简介
1.Go简介 Go语言是编译型.静态类型的类C的语言,并带有GC(垃圾收集器,garbage collection).这意味着什么? 另外,Go是一种非常严格的语言,它几乎总是要求我们"以标 ...
- Go基础系列:简单数据类型
每一个变量都有数据类型,Go中的数据类型有: 简单数据类型:int.float.complex.bool和string 数据结构或组合(composite):struct.array.slice.ma ...
- 设置防火强开机自启,以及没有成功的tomcat开机自启
防火墙 如果你的系统上没有安装使用命令安装 #yum install firewalld //安装firewalld 防火墙 开启服务 # systemctl start firewalld.serv ...
- Idea 常用功能汇总,工作中常用技巧,移出请说明原因,笔记花了好长时间汇总的
1.隐藏没用到的文件 比如 IDEA 的项目配置文件(.iml 和.idea),打开 Settings-File Types, 加入要隐藏的文件后缀. 2.常用技巧 2.1 通过Alt+F8查看变量 ...
- 本地yum仓库搭建,使用163yum源
如果内部网络没有连接Internet就在本地配置yum仓库 将操作系统镜像上传到服务器中,进行挂载 mount –o loop rhel-server-6.7-x86_64-dvd.iso /mnt ...
- C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.Int ...
- [PHP] 多进程通信-消息队列使用
向消息队列发送数据和获取数据的测试 <?php $key=ftok(__FILE__,'a'); //获取消息队列 $queue=msg_get_queue($key,0666); //发送消息 ...
- mysql函数技巧整理
IF(expr,v1,v2) expr表达式为true时返回v1,否则返回v2 IFNULL(v1,v2) 如果v1为NULL,返回v2 :v1不为NULL 则返回v1 CASE expr WHEN ...
- The JRE_HOME environment variable is not defined correctly This environment
昨天启动tomcat还好好的,今天不知道抽什么风,cmd中报错: The JRE_HOME environment variable is not defined correctly This env ...