十种常见排序算法可以分为两大类

  非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破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实现的更多相关文章

  1. 十大经典排序算法(python实现)(原创)

    个人最喜欢的排序方法是非比较类的计数排序,简单粗暴.专治花里胡哨!!! 使用场景: 1,空间复杂度 越低越好.n值较大: 堆排序 O(nlog2n) O(1) 2,无空间复杂度要求.n值较大: 桶排序 ...

  2. 十大经典排序算法总结 (Python)

    作业部落:https://www.zybuluo.com/listenviolet/note/1399285 以上链接是自己在作业部落编辑的排序算法总结- Github: https://github ...

  3. python实现十大经典排序算法

    Python实现十大经典排序算法 代码最后面会给出完整版,或者可以从我的Githubfork,想看动图的同学可以去这里看看: 小结: 运行方式,将最后面的代码copy出去,直接python sort. ...

  4. 用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并等

    本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序.选择排序.快速排序.冒泡排序.归并排序.希尔排序.插入排序.桶排序.基数排序.计数排序算法,想要学习的你们,继续阅读下去吧,如 ...

  5. 十大经典排序算法最强总结(含Java、Python码实现)

    引言 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面 ...

  6. python基础__十大经典排序算法

    用Python实现十大经典排序算法! 排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大, ...

  7. 十大经典排序算法+sort排序

    本文转自:十大经典排序算法,其中有动图+代码详解,本文简单介绍+个人理解. 排序算法 经典的算法问题,也是面试过程中经常被问到的问题.排序算法简单分类如下: 这些排序算法的时间复杂度等参数如下: 其中 ...

  8. 十大经典排序算法的 JavaScript 实现

    计算机领域的都多少掌握一点算法知识,其中排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大 ...

  9. JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)

    1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...

随机推荐

  1. Perl文件测试操作和stat函数

    在shell中通过test命令或者中括号[]可以进行文件测试以及其它类型的测试,例如判断文件是否存在,比较操作是否为真等等.perl作为更强大的文本处理语言,它也有文件测试类表达式,而且和shell的 ...

  2. Perl回调函数和闭包

    在Perl中,子程序的引用常用来做回调函数(callback).闭包(closure),特别是匿名子程序. 回调函数(callback) 关于什么是回调函数,见一文搞懂:词法作用域.动态作用域.回调函 ...

  3. java8 集合求差集、并集、交集

    前言 java8里最大亮点是lambda,让我们用习惯C# linq的语法,也能眼前一亮.但是比起C#的语法糖还是差的很远. 差集.并集.交集 @Test public void test1(){ L ...

  4. [转]简单科普私钥、地址、助记词、Keystore的区别

    本文转自:https://www.jianshu.com/p/d0a4a44685d3 很多人保管不好自己的虚拟财产,发生丢币的情况,很多都是因为不清楚私钥的概念. 私钥(Private Key) 比 ...

  5. [转]innodb的锁时间

    本文转自:https://www.cnblogs.com/sunss/p/3170132.html 观察innodb的锁时间,需要关注: mysqladmin extended-status -r - ...

  6. JQuery ajax的使用

    JQuery 真的是好东西       $.ajax({         type: "post",         url: "/DataCheck",   ...

  7. Android Studio RecyclerView用法

    首先创建一个布局 里面放一个文本 <TextView android:id="@+id/textView" android:layout_width="60dp&q ...

  8. Git中的"pull request"真正比较的是什么?

    前言 利用git版本控制工具时,我们通常会从主分支拉出新分支进行开发,开发完成后创建pr(也就是pull request),让其他小伙伴帮忙review,确定代码没有问题后再将新分支合并到主分支上.但 ...

  9. Object类型转换成自定义类型(向下转型)

    Object类型转换成自定义类型 场景: 从数据库或者别的途径接收对象的时候用Object,但是用的时候怎么object点(方法提示 | alt+'/'),都点不出自定义类型的方法. 比如,数据库查询 ...

  10. Cheating sheet for vim