https://github.com/TheAlgorithms/Python;本文内容出自于此。php
维基百科:冒泡排序(英语:Bubble Sort,台湾另一种译名为:泡沫排序)是一种简单的排序算法。它重复地走访过要排序的序列,一次比较两个元素,若是他们的顺序错误就把他们交换过来。走访数列的工做是重复地进行直到没有再须要交换,也就是说该数列已经排序完成。这个算法的名字由来是由于越小的元素会经由交换慢慢“浮”到数列的顶端。git
因为它的简洁,冒泡排序一般被用来对于程序设计入门的学生介绍算法的概念。github
特性:算法
最差时间复杂度:O(n^2)数组
最好时间复杂度:O(n)架构
平均时间复杂度:O(n^2)less
Python代码实现:ide
输出结果:final: [2, 4, 8, 13, 14, 26, 27, 28, 33, 35]svg
维基百科:插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工做原理是经过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,一般采用in-place排序(即只需用到O(1)的额外空间的排序),于是在从后向前扫描过程当中,须要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。oop
通常来讲,插入排序都采用in-place在数组上实现。具体算法描述以下:
若是比较操做的代价比交换操做大的话,能够采用二分查找法来减小比较操做的数目。该算法能够认为是插入排序的一个变种,称为二分查找插入排序。
若是目标是把n个元素的序列升序排列,那么采用插入排序存在最好状况和最坏状况。最好状况就是,序列已是升序排列了,在这种状况下,须要进行的比较操做需(n-1)次便可。最坏状况就是,序列是降序排列,那么此时须要进行的比较共有次。插入排序的赋值操做是比较操做的次数减去(n-1)次,(由于n-1次循环中,每一次循环的比较都比赋值多一个,多在最后那一次比较并不带来赋值)。平均来讲插入排序算法复杂度为O(n^2)。于是,插入排序不适合对于数据量比较大的排序应用。可是,若是须要排序的数据量很小,例如,量级小于千;或者若已知输入元素大体上按照顺序排列,那么插入排序仍是一个不错的选择。 插入排序在工业级库中也有着普遍的应用,在STL的sort算法和stdlib的qsort算法中,都将插入排序做为快速排序的补充,用于少许元素的排序(一般为8个或如下)。
特性:
最差时间复杂度:O(n^2)
最好时间复杂度:O(n)
Python代码的两种实现:
输出结果:final: [2, 4, 8, 13, 14, 26, 27, 28, 33, 35]
维基百科:归并排序(英语:Merge sort,或mergesort),是建立在归并操做上的一种有效的排序算法,效率为O(n log n)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个很是典型的应用,且各层分治递归能够同时进行。
归并操做(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操做。归并排序算法依赖归并操做。
原理以下(假设序列共有n个元素):
特性:
最差时间复杂度:O(nlogn)
最好时间复杂度:O(n)
平均时间复杂度:O(n)
Python代码的实现:
维基百科:快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),一种排序算法,最先由东尼·霍尔提出。在平均情况下,排序n个项目要(大O符号)O(nlogn)次比较。在最坏情况下则须要O(n^2)次比较,但这种情况并不常见。事实上,快速排序一般明显比其余O(nlogn)算法更快,由于它的内部循环(inner loop)能够在大部分的架构上颇有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法必定会结束,由于在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
在简单的伪代码中,此算法能够被表示为:
function quicksort(q) var list less, pivotList, greater if length(q) ≤ 1 { return q } else { select a pivot value pivot from q for each x in q except the pivot element if x < pivot then add x to less if x ≥ pivot then add x to greater add pivot to pivotList return concatenate(quicksort(less), pivotList, quicksort(greater)) }
特性:
最差时间复杂度:O(n^2)
最好时间复杂度:O(n)或O(nlogn)
平均时间复杂度:O(n^2)
Python代码的实现:
选择排序(Selection sort)是一种简单直观的排序算法。它的工做原理以下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,而后,再从剩余未排序元素中继续寻找最小(大)元素,而后放到已排序序列的末尾。以此类推,直到全部元素均排序完毕。
选择排序的主要优势与数据移动有关。若是某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,所以对n个元素的表进行排序总共进行至多(n-1)次交换。在全部的彻底依靠交换去移动元素的排序方法中,选择排序属于很是好的一种。
特性:
最差时间复杂度:O(n^2)
最好时间复杂度:O(n^2)
平均时间复杂度:O(n^2)
Python代码的实现:
维基百科:希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的如下两点性质而提出改进方法的:
原始的算法实如今最坏的状况下须要进行O(n2)的比较和交换。V. Pratt的书对算法进行了少许修改,可使得性能提高至O(n log2 n)。这比最好的比较算法的O(n log n)要差一些。
希尔排序经过将比较的所有元素分为几个区域来提高插入排序的性能。这样可让一个元素能够一次性地朝最终位置前进一大步。而后算法再取愈来愈小的步长进行排序,算法的最后一步就是普通的插入排序,可是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
假设有一个很小的数据在一个已按升序排好序的数组的末端。若是用复杂度为O(n2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,因此小数据只需进行少数比较和交换便可到正确位置。
一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法自己仅仅对原数组进行排序(经过增长索引的步长,例如是用i += step_size
而不是i++
)。
例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],若是咱们以步长为5开始进行排序,咱们能够经过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:
13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10
而后咱们对每列进行排序:
10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45
将上述四行数字,依序接在一块儿时咱们获得:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,而后再以3为步长进行排序:
10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45
排序以后变为:
10 14 13 25 23 33 27 25 59 39 65 73 45 94 82 94
最后以1步长进行排序(此时就是简单的插入排序了)。
特性:
最差时间复杂度:O(n^2)
最好时间复杂度:O(n)
平均时间复杂度:取决于步长
Python代码的实现:
冒泡,插入,选择排序的平均时间复杂度比较: