本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码。
常见排序算法比较

相关概念
- 稳定: 如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
- 不稳定: 如果a原本在b的前面,而a=b, 排之后a可能会出现在b的后面。
- 时间复杂度: 对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
- 空间复杂度: 是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
冒泡排序
基本思想:从无序序列头部开始,进行两两比较,根据大小交换位置,直到最后将最大(小)的数据元素交换到了无序队列的队尾,从而成为有序序列的一部分;下一次继续这个过程,直到所有数据元素都排好序。
1 | |
快速排序
基本思想:基于分治法。在待排序表L[1…n]中任取一个元素pivot作为基准,通过一趟排序算法将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1…k-1]中的所有元素小于pivot,L[k+1…n]中的所有元素大于等于pivot,则pivot放在了其最终位置L[k]上,这个过程称为一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素都放在了其最终位置上。
1 | |
1 | |
1 | |
直接插入排序
基本思想: 将数组中的所有元素依次和前面的已经排好序的元素相比较(依次),如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过。
1 | |
希尔排序
基本思想:希尔排序也称缩小增量排序;希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时(用gap = gap/3+1 控制),保证了最后一次进行直接插入排序,算法终止。
1 | |
简单选择排序
基本思想:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。
1 | |
堆排序

基本思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
- 步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
- 此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 为 倒数第二层左右边的节点),从左至右,从下至上进行调整。
- 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后将剩余的n-1个元素继续调整堆(只需调整堆顶元素),再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。
1 | |
归并排序
基本思想:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列; 即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
2-路归并:
- 分解:将含有n个元素的待排序表分成含n/2个元素的子表,采用2路归并排序算法对两个子表递归地进行排序。
- 合并:合并两个已经排序的子表得到排序结果。
1 | |