快速排序
快速排序是不稳定的排序
排序最快的时间复杂度n*log(n),基本上每种排序都是优化排序的次数,每一次确定一个数都是O(n)级别,但是排序的次数各种排序算法是不一样的
功能描述:
快速排序的优化在于如何选择基准数
每次选一个基准数(默认是第一个),
把小于基准数的数据放到左边子数组,大于基准数的数据放到右边子数组,然后分别对左右子数组进行递归操作
第一次排好一个数
第二次排好三个数
第三次排好七个数
依次类推每次确定的数的个数是以指数增长的,
快速排序的优化:
一、三数取中法,解决数据基本有序的(就是找到数组中最小下标,最大下标,中间下标的数字,进行比较,把中间大的数组放在最左边)
二、随机选取基准。引入的原因:在待排序列是部分有序时,固定选取枢轴使快排效率底下,要缓解这种情况,就引入了随机选取枢轴。
思想:取待排序列中任意一个元素作为基准
三、优化小数组的交换,就是为了解决大才小用问题。
动图演示
代码实现:
public static void main(String[] args) {
Integer[] arr = new Integer[]{45,8,5,3,6,2,3,5,8,9,1,32,14,32,16,7,43,45,67,86,34,32,11,44,66,22,33,87,96,65,54,43,32,15,63,75,78};
List<Integer> a = Arrays.asList(arr);
a=sort(a);
for (int index:a) {
System.out.print(index+" ");
}
}
/*
第一个sort是用List实现的,比较好理解,会新建list
*/
private static List<Integer> sort(List<Integer> arr){
//如果传进来的list没有长度,直接返回
if(arr.size()==0){
return arr;
}
int flag = arr.get(0);
List<Integer> left = new ArrayList<>();
List<Integer> right = new ArrayList<>();
for (int i = 1; i < arr.size(); i++) {
//把小于flag的放在左边集合,大于flag的放在右边集合
if(arr.get(i)>=flag){
right.add(arr.get(i));
}else {
left.add(arr.get(i));
}
}
//分别把左右集合递归排序
left = sort(left);
right = sort(right);
//把左右集合和flag放到新的集合中返回
List<Integer> newList = new ArrayList<>();
newList.addAll(left);
newList.add(flag);
newList.addAll(right);
return newList;
}
//直接在原数组上面进行元素的挪动,不好理解,但是省内存
public static void sort(int left,int right,int[] arr){
int i=left,j=right;
if(left>=right) return;
int temp = arr[left];
while(i<j){
//先从右边开始遍历
while(arr[j] >= temp && i < j) j--;
while(arr[i] <= temp && i < j) i++;
if(i<j){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
arr[left] = arr[i];
arr[i]=temp;
sort(left,i-1,arr);
sort(i+1,right,arr);
}