总结一下目前学过的所有排序算法:
1 冒泡排序
2 选择排序
3 快速排序
4 插入排序
5 希尔排序
6 堆排序
7 计数排序
8 合并排序
9 基数排序
10 桶排序
排序分为稳定排序和非稳定排序。
另外还有原地排序,是指不申请多余的存储空间来进行排序。
下面分别小结以上排序算法:
1 冒泡排序:
冒泡排序的思想很简单:从第一个元素起,每相邻两个元素进行比较,较大的元素下沉。所以每一轮比较下来,最大的元素沉底,较小的元素上浮。
时间复杂度: n * n
属于稳定排序和原地排序。
2 选择排序
思想:在未排序序列中找到最小元素,放到起始位置(与起始元素交换位置)。在剩余元素中挑出最小元素,存放到已排序序列末尾。以此类推。
时间复杂度:n * n
属于不稳定排序和原地排序。
选择排序的交换次数比冒泡排序少。
3 快速排序
快速排序采用了分治法,可以用递归实现。其基本思想是通过一趟排序,将待排序序列分为两个部分,其中一部分的元素都比另一部分的元素小。之后再分别对这两个部分进行相似的快速排序。最终得到有序序列。
时间复杂度:最差(n * n) 最优(n*logn)
属于不稳定排序,原地排序。
4 插入排序
思想:将数据插入已经排好序的序列中。每次插入数据,从后向前扫描已经排好序的数据,找到插入位置后,将其后元素向后移动一个位置。
时间复杂度:n * n
属于稳定排序和原地排序。
5 希尔排序(shell)
希尔排序是插入排序的一种改进。其基本思想是按照不同的步长对元素进行插入排序。首先将要排序的序列按照某个步长d分为若干组,对每组元素进行插入排序。再用一个较小的步长分组,每组进行排序。最终步长减为1进行排序。
希尔排序的关键是步长的选择。
时间复杂度:根据步长序列的不同而不同 最优(n*log2n)
属于不稳定排序和原地排序。
6 堆排序
堆的定义(百度百科):
n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
(1) ki≤K2i且ki≤K2i+1 或
(2)Ki≥K2i且ki≥K2i+1(1≤i≤ n) //ki相当于二叉树的非叶结点,K2i则是左孩子,k2i+1是右孩子
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
堆排序首先把要排序的序列看做顺序存储的二叉树,调整元素的存储顺序使之成为一个堆。之后将堆顶元素与序列的最后一个元素对调。然后对前面的n-1个元素进行调整使之成为一个堆,将堆顶与第n-1个原素对调。以此循环。
时间复杂度:nlogn
属于不稳定排序和原地排序
7 计数排序
计数排序不是比较排序,所以排序速度快于任何比较排序算法。其基本思想为使用一个辅助的数组C。C中的第i个元素是待排序数组A中值等于i的元素的个数。这样就很容易知道比i小的元素的个数,从而定位得到A中元素的最终位置。
时间复杂度:当待排序的元素是n个0到k之间的整数时,时间复杂度是n + k
属于稳定排序和非原地排序
8 合并排序
思想:将前后相邻的两个序列两两合并,不断重复从而得到有序序列
时间复杂度:nlogn
属于稳定排序和非原地排序
9 基数排序
思想:从数据的低位到高位排序。(是桶排序的扩展)
时间复杂度:n
属于稳定排序和非原地排序
10 桶排序
思想:将[0, 1)划分为n个相同大小的子区间,将n个记录分配到这些区间中。对于落在每个区间内的数据进行排序(插入排序),最终将各个区间首尾连接即可。
时间复杂度:n
属于稳定排序和非原地排序
适用于关键字取值范围较小的情况