排序--快速排序--详细分析

来源:互联网 发布:python的idey 编辑:程序博客网 时间:2024/04/30 07:54
        快速排序是一种分治的排序算法。它将一个数组分成两个子数组,将两部分独立的排序。它和归并排序是互补的。
        归并排序将数组分成两个子数组分别排序,并将已经有序的两个子数组按照大小放入也就是归并到一个数组中,形成有序的数组。而快速排序则是当两个子数组都有序时,整个数组自然有序了。

话不多说,示例代码解释:
package Util;
 
public class KuaiPaiSort {
 
public static void main(String[] args) {
int[] a = { 9, 4, 7, 1, 7, 10, 45 ,1,1,8,23,100,1};
int len = a.length;
sort(a,0,len-1);
for (int i = 0; i < len; i++) {
System.out.print(a[i]+" ");
}
}
static int getMiddle(int [] list,int left,int right){//每次寻找到的中心点总是位置已经排好的
int temp;//交换时的中间变量
//进行一趟快排 返回中心点位置
int mid=list[left];    //通常把中心置于 a[0] 即新数组的第一个位置
while(left<right){
while(left<right&&list[right]>=mid){  //找到比中心点小的数 交换
right--;
}
temp=list[right];
list[right]=list[left];
list[left]=temp;
while(left<right&&list[left]<=mid){
left++;
}
temp=list[right];
list[right]=list[left];
list[left]=temp;
}
list[left]=mid;//中心移到正确位置 这是关键,确定了位置 下一次不进行比较 并且到这个地方 left已经是mid了
return left;
}
static int[] sort(int [] list,int left,int right){
if(left<right-1){//不断找到中间点,交换两边值,最终构成有序的数组
int mid=getMiddle(list, left, right);
sort(list, left, mid-1);
sort(list, mid+1, right);
}
return list;
}
}
    分析:
    先看getMiddle()方法,这个方法找到一个点调换点的两边的数组元素,让左边的小于mid,右边的大于mid。可以自定义比较的方法及内容。
   
三个参数,list是要处理的子数组,left是此子数组的首个元素在整个源数组的位置,right是尾元素的位置。
  
方法中,先把首字母确定为mid值,继续往下走,当mid右边的 list[right]>=mid 时,位置合理,此时right--,记住,right是整个源数组的下标,即向左移一位。直到遇到list[right]<mid。跳出,继续往下,把这个元素交换到左边去。

继续往下,把左边的进行比较,当遇到第一个比mid大的值时,和右边交换。

这样的一个过程在大循环while(left<right)中,那么它会不断地交换直到left=right为止,此时再将list[left]的值赋为mid,(比如说本来mid在整个源数组的第三位,而排好序后的数组中 mid这个值是在第五位的,那么这个赋值便是把这个数组中的第五位改成mid值,这样每次相对确定一个数的确切位置)。

getMiddle()最后返回的就是传入数组首元素的一个确切的位置,并且把给这个位置赋上了正确的值。

    再看sort()方法 ,当left<right-1(即两个相邻时就不用比了)时,getMiddle方法得到切分点,这时候right和left值已经被改变,它们总是不断逼近mid的。接下来两个,递归对mid左边sort,再右边sort,同时对上一个子数组不断地切分,最终返回放好一个元素的字数组,然后递归继续。不满足left<right-1时,会有一个结束,当两个都结束时,所有的元素都已被摆在了正确的位置上。
  
    快排效率很高,它是原地排序,且内循环很小,复杂度NlgN。其他无法比拟。

    大体思想便是这个了……后面我会再把其他几个排序也分析下

2015/08/08
0 0
原创粉丝点击