踏踏实实积累,不要浮躁
(1):快排应该是工程上使用最多的一种算法了,时间复杂度O(nlogn) 不稳定,原地的排序算法
思想:利用递归依次找到数组最后一个元素在排序后的位置,
package sort;
import edu.princeton.cs.algs4.StdRandom;
import tools.Util;
public class quickSort {
public static void sort(int[] arr){
// 将原本的数组打乱,消除对输入的依赖 保持随机性
StdRandom.shuffle(arr);
sort(arr,0,arr.length - 1);
}
public static void sort(int[] arr,int low,int high){
if(high <= low){
return;
}
int j = partition(arr,low,high);
sort(arr,low,j-1);
sort(arr,j+1,high);
}
private static int partition(int[] arr, int low, int high) {
int compar = arr[high];
int left = low - 1; // 先减一是为了后面格式统一++left 和 --right
int right = high ;
while (true){
while (arr[++left] < compar){
if(left == high){
break;
}
}
while (arr[--right] > compar){
if (right == low){
break;
}
}
if(left >= right){
break;
}
Util.swap(arr,left,right);
}
Util.swap(arr,left,high); // 这边进行交换只能用 left
return left;
}
public static void main(String[] args) {
int[] arr = {3,2,6,4,9,1,5,99,100,35,45,100,234,5454,656,654,67,657,6,76,546,54,53,34,2};
sort(arr);
Util.println(arr);
}
}
说明:
1:StdRandom.shuffle(arr); 是为了消除 对输入数组的依赖,保证数据随机性
2:下面的代码是对 快排的过程做的过程抽象,让代码看起来更直观,注意sort(arr,low,j-1)和sort(arr,j+1,high)不能写j这样会导致堆栈溢出死递归
if(high <= low){
return;
}
int j = partition(arr,low,high);
sort(arr,low,j-1);
sort(arr,j+1,high);
3:重点在原地partition函数 思想懂了其实代码也很简单
(2):快速排序优化 思路
1:在数据量比较小的时候切换成插入排序,小数据量的表现上插入排序比快速排序快
2:用三向切分快速排序,考虑了重复元素的情况在含有大量重复元素的数据集中性能有较大的提升,比归并排序性能要好
思想:使用三个指针 lt , i ,gt 初始时 lt 和 i 相等,compar取值arr[low]然后进行如下规则的交换元素
1:arr[i] < compar 时 交换 arr[lt] 和 arr[i] 同时 lt 和 i 都加1
2:arr[i] > compar 时 swap(arr,i,gt--) 交换i位置和gt位置元素的值 同时将gt值减1
3:当arr[i] = compar 时 i ++ 继续进行如上循环
public class quickSort2 {
public static void sort(int[] arr,int low,int high){
if(low >= high){
return;
}
int lt = low;
int i = low + 1;
int gt = high;
int compar = arr[low];
while (i <= gt){
if(arr[i] < compar){
Util.swap(arr,i++,lt++);
}else if(arr[i] > compar){
Util.swap(arr,i,gt--); // 注意这边是 i
}else {
i++;
}
}
sort(arr,low,lt -1);
sort(arr,gt+1,high);
}
public static void main(String[] args) {
int[] arr = {2,1,5,3,3,1,7,6,6,10};
sort(arr,0,arr.length - 1);
Util.println(arr);
}
}