【算法】排序算法汇总1
1. 冒泡排序:
思路:进行相邻比较后,每一轮将最值移动到一端;平均时间复杂度:需要进行n-1轮,内层有n/2次的可能交换,合计是O(n²);
最坏时间复杂度:需要进行n-1轮,内层每次有n-1-i(i是当前轮)的交换次数,合计是O(n²);
最优情况:是一个原本就有序的数组,O(n);
空间复杂度:原地交换,O(1);
稳定排序;
2. 鸡尾酒排序(双向冒泡排序):思路:以冒泡排序的思路,从左端冒到右端,再从右端冒到左端,对两端有序更好;
平均时间复杂度:n个元素就要比较n-1轮,每次平均要比较n/2个元素,合计是O(n²);
最坏时间复杂度:比较n-1轮,每次需要比较n-1-i次(i是当前轮),合计是O(n²);
最优情况:同冒泡排序最优情况,一个原本就有序的数组,O(n);空间复杂度:原地交换,O(1);
稳定排序;
3. 快速排序
思路:选出一个基准数,然后根据基准数将当前的数组分为大于组和小于组;平均时间复杂度:分的轮次约为O(logn),每轮平均要比较(n-i)/2(i是当前轮),合计是O(nlogn);
最坏时间复杂度:每次都只挑选到边缘的位置,无法将一个数组根据基准数分成两份,所以递归的高度会变成n轮,合计为O(n²);
空间复杂度:这里的空间复杂度为函数的引用占用,它直接与栈的深度相关,即平均为O(logn),最坏是O(n);不稳定排序;
4. 堆排序
思路:先进行建堆,之后进行堆内调整以达到有序,分为最大堆和最小堆;
建堆:采用Floyd建堆法,只遍历大约一半的节点,每个节点的操作成本不同,约合计为O(n);时间复杂度:无最好和最坏的差别,需要提取n次,每次复杂度为O(logn),合计为O(nlogn);
空间复杂度:在原堆中操作,为O(1);
不稳定排序;
5. 计数排序
前提:键值是整数,且范围有限;
流程:1. 统计每个数的出现频次,时间复杂度为O(n);2. 计算每个键的起始输出位置(累计位置),复杂度为O(k);3. 再遍历一遍排序好的数组,时间复杂度为O(n);时间复杂度:合计为O(n + k);
空间复杂度:用于存放的值的空间大小,合计为O(k);当k与n的数量级差不多时,会让排序更快;
累计位置的方式可以稳定排序;
6. 桶排序
前提:需要被排序的值均匀地被分配在区间内;流程:1. 建立b个桶,时间复杂度为O(b),扫描所有的元素并分配到桶内时间复杂度为O(n);2. 分别对桶的内部进行排序;3. 按桶的顺序输出桶内的每个元素;
期望时间复杂度:假设要被排序的数组均匀分布,桶数b与n同阶,即在同一个数量级:桶内的排序若用的是时间复杂度为O(n²)的排序算法,那么合计的时间复杂度为b*O((n/b)²) = O(n²/b), 在此假设b约等于n,那么最后的结果为O(n);
桶内的排序若用的是时间复杂度为O(nlogn)的排序算法,那么合计的时间复杂度为b*O((n/b)log(n/b)) = O(n²/b), 在此假设b约等于n,那么最后的结果为O(n);
最坏的时间复杂度:所有的元素都堆在一个桶内,合计为O(n²);
是否稳定取决于桶内的排序算法是否是稳定的
