【Java】快速排序
什么是快速排序(快排)
快速排序由冒泡排序演变而来,使用分治法。
快速排序属于交换排序,通过元素之间的比较和交换来排序。
不同的是,冒泡排序每次只移动一个元素到数列一端,而快速排序选取一个基准,比它小的往左边排,比它小的往右边排,把数列拆解成两个部分。
尤其很多同学不知道为什么快速排序的时间复杂度是O(nlogn)?之后将做以解释。
实现细节
每一次快速排序,需要n轮二分法,(n为元素个数)。
每一次二分法选取基准,除基准外元素排序好后,最后一步将基准与左右指针交叉点交换,而左右指针的交叉点位置是有说法的。
如果采取左边第一个元素为基准,那么左指针循环条件有(arr[l]<=key),这里key为基准,而右指针循环条件为(arr[r]>key),可以看到"="将第一个元素本身也算在里面,这样可以使左指针初始指向第一个元素时正常往后移。
在交换完毕基准和左右指针交叉点,也就是最后一个比基准小的数,我们进行下一步。(这里假设以左边第一个元素为基准)
而每次一轮二分法之后,需要递归处理剩下的左右两边,因为一轮只是分出一个基准左右两边的数,而这时候左右两边本身是没有排好的,我们需要继续选取左边第一个元素和上次的基准左边,也就是l-1,进行排序。
以此往复如果begin=end,也就是细分为一个数时,我们return,也就是说自此,二分法完毕,所以回过头我们就知道了,假设数组长度为2的n次方,每次二分法就会进行logn次,而又需要进行n次二分法,所以需要O(nlogn)的时间复杂度。
代码如下:
public static void quickSort1(int[] arr, int begin, int end){
if(begin>=end){
return;
}
int key=arr[begin],l=begin,r=end;
while(l!=r){
while(l<r&&arr[r]>key){
r--;
}
while(l<r&&arr[l]<=key){
l++;
}
int temp=arr[l];
arr[l]=arr[r];
arr[r]=temp;
}
int temp=arr[begin];
arr[begin]=arr[l];
arr[l]=temp;
quickSort1(arr,begin,l-1);
quickSort1(arr,l+1,end);
}
public static void main(String[] args) {
int[] a={3,10,30,6,15,1,7,17};
int n=a.length-1;
quickSort1(a,0,n);
for(int i=0;i<=n;i++){
System.out.println(a[i]);
}
}
需要注意的是,以下极端情况会变为平方。

1万+

被折叠的 条评论
为什么被折叠?



