https://www.cnblogs.com/onepixel/p/7674659.html这个文章很nice

https://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338这个动图优秀

https://www.icourse163.org/course/ZJU-93001   MOOC浙大 数据结构 陈越、何钦铭

VisuAlgo - visualising data structures and algorithms through animation    数据结构与算法的可视化网站  更容易让人感性理解各种算法

冒泡排序、选择排序、插入排序这三个是最慢也是最经典的三个排序算法

快速排序对于大的乱数串列一般相信是最快的已知排序

冒泡排序 bubble sort

最简单的排序算法,也是效率最差的,因为它必须在最终位置知道前交换,浪费许多“交换操作”

如果列表已经排序,则是最好情况,遍历期间无需交换,如果发现已经排序,可以提前终止,这种修改下的冒泡通常称为短冒泡排序

时间复杂度: 平均O(n^2)    最差O(n^2)     最好O(n)

空间复杂度:O(1)

稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #冒泡排序
for i in range(len(alist)-1):
for j in range(len(alist)-1-i):
if alist[j] > alist[j+1]:
alist[j],alist[j+1] = alist[j+1],alist[j] #排序结果输出
print('sorted:',alist)

选择排序 selection sort

选择排序改进了冒泡排序,每次遍历列表只做一次交换

时间复杂度:平均O(n^2)    最差O(n^2)    最好O(n^2)

空间复杂度:O(1)

不稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #选择排序
for i in range(len(alist)-1):
least = i
for j in range(i+1,len(alist)):
if alist[j] < alist[least]:
least = j
if least != i:
alist[least],alist[i] = alist[i],alist[least] #排序结果输出
print('sorted:',alist)

插入排序 insertion sort

它始终在列表的较低位置维护一个排序的子列表,然后将每个新项 “插入” 回先前的子列表,使得排序的子列表成为较大的一个项

时间复杂度: 平均O(n^2)    最差O(n^2)     最好O(n)

空间复杂度:O(1)

稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #插入排序
for i in range(1,len(alist)):
j = i;
while j>0 and alist[j-1]>alist[j]:
alist[j-1],alist[j] = alist[j],alist[j-1]
j -= 1 #排序结果输出
print('sorted:',alist)

希尔排序 shell sort

是1959年Shell发明,第一个突破O(n^2)的排序,是对简单插入排序的改进,与插入排序不同的是它优先比较距离较远的元素,又叫“递减增量排序”

是针对插入排序以下2特点改进:在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;一般来说是低效的,因为插入排序每次只能将数据移动一位

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步

gap概念,gap递减,最后一步就是插入排序,但是此时几乎已经排好序了

gap是希尔排序核心

出名的gap设置Marcin Ciura's gap sequence ,gaps = [701, 301, 132, 57, 23, 10, 4, 1],不过下面例子用数组长度不断整除2得到的序列作为gaps

时间复杂度:平均O(n(logn)^2)    最差O(n^2)    最好O(n)

空间复杂度:O(1)

不稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #希尔排序
gap = len(alist)//2
while gap>0:
#对每个gap做插入排序
for i in range(gap,len(alist)):
j = i
while j>=gap and alist[j-gap]>alist[j]:
alist[j-gap],alist[j] = alist[j],alist[j-gap]
j -= gap
gap = gap//2 #排序结果输出
print('sorted:',alist)

归并排序 merge sort

分而治之的策略来提高性能,是分治法的典型应用

归并排序是一种递归算法,不断将列表拆分为一半

二路归并 多路归并

缺点是在合并过程需要额外存储空间

时间复杂度: 平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

空间复杂度:O(n)

稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #归并排序
def merge_sort(ilist):
def merge(left, right):
result = []
while left and right:
result.append((left if left[0] <= right[0] else right).pop(0))
return result + left + right if len(ilist) <= 1:
return ilist
mid = len(ilist) // 2
return merge(merge_sort(ilist[:mid]), merge_sort(ilist[mid:])) #排序结果输出
print('sorted:',merge_sort(alist))

快速排序 quick sort

与归并排序相同,采用分治法,而不使用额外存储

是对冒泡排序的改进

通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效的达成

简单的版本和归并排序一样不好,需要额外存储空间,但是可以改为in-place版本,也就不要额外空间了

时间复杂度: 平均O(nlogn)    最差O(n^2)      最好O(nlogn)

空间复杂度:O(nlogn)

不稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #快速排序
def quick_sort(ilist):
length = len(ilist)
if length <= 1:
return ilist
else:
# Use the last element as the first pivot
pivot = ilist.pop()
# Put elements greater than pivot in greater list
# Put elements lesser than pivot in lesser list
greater, lesser = [], []
for element in ilist:
if element > pivot:
greater.append(element)
else:
lesser.append(element)
return quick_sort(lesser) + [pivot] + quick_sort(greater) #排序结果输出
print('sorted:',quick_sort(alist))

堆排序 heap sort

是对选择排序的一种改进

利用堆这种数据结构所设计的算法 近似完全二叉树

堆通常通过一维数组实  大根堆  小根堆

时间复杂度:平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

空间复杂度:O(1)

不稳定

#测试输入数组
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #堆排序
def heapify(unsorted, index, heap_size):
largest = index
left_index = 2 * index + 1
right_index = 2 * index + 2
if left_index < heap_size and unsorted[left_index] > unsorted[largest]:
largest = left_index if right_index < heap_size and unsorted[right_index] > unsorted[largest]:
largest = right_index if largest != index:
unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest]
heapify(unsorted, largest, heap_size) def heap_sort(unsorted):
n = len(unsorted)
for i in range(n // 2 - 1, -1, -1):
heapify(unsorted, i, n)
for i in range(n - 1, 0, -1):
unsorted[0], unsorted[i] = unsorted[i], unsorted[0]
heapify(unsorted, 0, i)
return unsorted #排序结果输出
print('sorted:',heap_sort(alist))

Python经典排序算法的更多相关文章

  1. python 经典排序算法

    python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...

  2. 经典排序算法总结与实现 ---python

    原文:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/ 经典排序算法在面试中占有很大的比重,也是基础,为了未雨绸缪,在寒假里整理并用P ...

  3. 经典排序算法及python实现

    今天我们来谈谈几种经典排序算法,然后用python来实现,最后通过数据来比较几个算法时间 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据 ...

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

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

  5. 经典排序算法的总结及其Python实现

    经典排序算法总结: 结论: 排序算法无绝对优劣之分. 不稳定的排序算法有:选择排序.希尔排序.快速排序.堆排序(口诀:“快速.选择.希尔.堆”).其他排序算法均为稳定的排序算法. 第一趟排序后就能确定 ...

  6. 经典排序算法及总结(python实现)

    目录 1.排序的基本概念和分类 排序的稳定性: 内排序和外排序 影响内排序算法性能的三个因素: 根据排序过程中借助的主要操作,可把内排序分为: 按照算法复杂度可分为两类: 2.冒泡排序 BubbleS ...

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

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

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

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

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

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

随机推荐

  1. android如何让checkbox实现互斥以及android验证端cession登录注意事项

    1.CheckBox有一个监听器OnChangedListener,每次选择checkbox都会触发这个事件, 里边有一个参数isChecked,就是判断checkbox是否已经选上了的,可以在这判断 ...

  2. JS json对象(Object)和字符串(String)互转方法

    [JS json对象(Object)和字符串(String)互转方法] 参考:https://blog.csdn.net/wenqianla2550/article/details/78232706 ...

  3. 关于java中MD5加密(可直接使用)

    本文转自:http://www.cnblogs.com/solove/archive/2011/10/18/2216715.html 上部分是转载的关于字符串的加密,后半部分则比较全,包括字符串.文件 ...

  4. 前端——语言——Core JS——《The good part》读书笔记——第三章节(Object)

    本章介绍对象. 在学习Java时,对象理解为公共事物的抽象,实例为具体的个例,对象为抽象的概念,例如人为抽象的概念,具体的个例为张三,李四. Java对象种类多,包含普通类,JavaBean,注解,枚 ...

  5. linux shell let, expr 命令详解

    linux命令之let.exprshell程序中的操作默认都是字符串操作,在运行数学运算符的时候可能得到意想不到的答案: var=1var=$var+1echo $var 将输出 1+1从这个例子中可 ...

  6. eclipse中怎么导入git库下载下来的web项目

    总的看来是有两种方式: 方式一:可以对已经从版本库下载到本地的项目操作(Maven导入) 你可以通过公司提供的内部的版本库的网址登录版本库,之后在里面下载自己想要的那个版本的代码包,见下图 点击右侧的 ...

  7. Linux查看mysql是否启动的命令

    使用命令 # service mysqld status 或者 # service mysql status 来查看mysql 的启动状态. 如果是 mysqld is stopped 那就说明mys ...

  8. 讲解一下类的继承super

    class Test1(object): def __init__(self,ids): self.ids=ids class Par(Test1): def __init__(self,ids,us ...

  9. django 模版查找路径

    路径的配置,模版上下文的配置等.模版路径可以在两个地方配置. 1.'DIRS':这是一个列表,在这个列表中可以存放所有的模版路径,以后在视图中使用render或者render_to_string渲染模 ...

  10. php中的elseif和else if

    以前的时候还没注意到,知道进入公司,看的代码多了点,时常看到elseif的分支,而我自己时常用的是else if,于是就注意到,他们既然都可以用,那么他们的却别在哪儿呢? 通过查询,原来,确实有点小小 ...