插入排序
-
直接插入排序
- 原理:一开始将数据分为两部分,初始数据当做无序,每一次从待排序队列中取出一个值,放到已经排序好的队列中,然后将其调整有序,再取下一个值,直到待排序队列中没有值。
- 调整规则:将待插入的值和有序队列中的所有值从右向左逐个比较,找到一个小于或者等于自己的值,则停下来,插入到当前位置的下一个位置。
- 特点:时间复杂度为O(n^2),适合小数据量排序;数据越有序,效率越高;是稳定的排序算法,即相等元素的相对顺序在排序前后不会改变。
-
折半插入排序
- 原理:是对直接插入排序的改进,通过折半查找法(也称二分查找法)来加快寻找插入点的速度。
- 过程:在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],则每轮比较时将待插入元素与a[m](m=(low+high)/2)相比较,如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。
- 特点:比直接插入排序减少了关键字之间比较的次数,速度更快,但记录移动的次数没有变,所以时间复杂度仍然为O(n^2);是稳定的排序算法。
-
希尔排序
- 原理:是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。希尔排序先对数据进行了分组,再在组内分别进行插入排序,排序完再对数据分成更小的组进行排序,直到组内只有1个元素的简单插入排序。
- 分组方法:根据增量increment安排分组,即increment个数分为一组,在数据中表现为每increment个数取一个划为一组。每次分组增量都在递减,递减的规律没有特别规定,一般是取increment为数据长度length的一半,再不断减半到为1。
- 特点:平均时间复杂度为O(n2)之间;由于在不同小组做插入排序时有较大幅度地变换数据的位次的可能性,所以是不稳定的排序算法。
交换排序
-
冒泡排序
- 原理:通过多次遍历待排序的数列,比较相邻元素的值,并在必要时交换它们的位置,从而将最大的元素逐步“冒泡”到数列的末尾。这个过程会重复进行,直到整个数列有序为止。
- 特点:时间复杂度在最好情况下为O(n)(数组已经有序时),最坏情况下为O(n2);是稳定的排序算法。
-
快速排序
- 原理:采用分治法的一个非常典型的应用。通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
- 特点:平均时间复杂度为O(n log n),但在最坏情况下(如数组已经有序)时间复杂度为O(n^2)。
选择排序
-
简单选择排序
- 原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
- 特点:不稳定排序,时间复杂度为O(n^2),但不需要额外的存储空间。
-
堆排序
- 原理:利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质,即子节点的键值或索引总是小于(或者大于)它的父节点。
- 特点:不稳定排序,时间复杂度为O(n log n),不需要额外的存储空间。
其他排序
-
归并排序
- 原理:采用分治法的一个应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
- 特点:稳定排序,时间复杂度为O(n log n),但需要额外的存储空间。
-
基数排序
- 原理:是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。
- 特点:稳定排序,时间复杂度为O(nk),其中n是排序元素个数,k是数字位数。