快速排序:
时间复杂度:时间复杂度主要取决于每次拆分的时间。是n*log(n)
空间复杂度:在合并的时候,没有使用额外的存储空间,所以时间复杂度是O(1)
原地排序算法:是原地排序算法。
稳定排序算法:在排序的时候,前后大小相等的元素,不能保证排序后的顺序一致。
如果从前往后排,则比中间值大的元素不能确保顺序一致,
如果从后往前排,则比中间值小的元素不能确保顺序。
时间复杂度计算方法:
T(n) = n 每次拆分后需要排序的时间复杂度是O(n)
S(n) = n * 拆分次数。 每次拆分几乎是对半拆分所以 2^m = n , m = log(n) 次
因此 S(n) = n* log(n)
package cm.com.algorithm.sort;
/**
* 快速排序:
* 快速排序的核心思想是:
* 取一个值,找到它在数组中的位置,
* 使得,这个值左边的数字都比这个值小,右边的数字都比这个值大。
* 依次递归,知道数组长度为1.
*
* @author liushuai13@meicai.cn
* @date 2019-06-08 18:21
*/
public class QuickSort {
private static int[] intArray = {9,7,5,3,6,5,8,9,5,4};
public static void main(String[] args) {
sort();
printArray();
}
/**
* 对数组排序
*/
private static void sort(){
int begin = 0;
int end = intArray.length - 1;
spilit(intArray,begin,end);
}
private static void spilit(int[] intArray,int begin,int end){
int oldbegin = begin; //初始begin
int oldend = end; //初始end
int num = intArray[end]; //中间值
int index = end; // 中间值的位置
end --;
//将数组中间值左边的元素全部比中间值小,右边的数字全都比中间值大
while (end - begin >= 0 ){
if (intArray[end] < num){
int temp = intArray[begin];
intArray[begin] = intArray[end];
intArray[end] = temp;
begin++;
}else {
intArray[end + 1] = intArray[end];
index = end;
end --;
}
}
intArray[index] = num;
//设定递归的递归条件和终止条件
//中间值前一半递归
if (index - 1 - oldbegin > 1){
spilit(intArray,oldbegin,index - 1);
}else if(index - 1 - oldbegin == 1){
if (intArray[oldbegin] > intArray[index - 1]){
int temp = intArray[oldbegin];
intArray[oldbegin] = intArray[index - 1];
intArray[index - 1] = temp;
}
}
//中间值后一半递归
if (oldend - (index + 1) > 1){
spilit(intArray,index + 1,oldend);
}else if (oldend - (index + 1) == 1){
if (intArray[index + 1] > intArray[oldend]){
int temp = intArray[index + 1];
intArray[index + 1] = intArray[oldend];
intArray[oldend] = temp;
}
}
}
/**
* 打印数组
*/
private static void printArray(){
for (int i = 0; i < intArray.length; i++) {
if ( i < intArray.length - 1 ){
System.out.print(intArray[i]+",");
continue;
}
System.out.println(intArray[i]);
}
}
}
快速排序原理示意图:
图片来源于-极客时间-数据结构与算法之美