快速排序

来源:互联网 发布:开源的推荐系统算法库 编辑:程序博客网 时间:2024/06/03 13:29
/** * 快速排序 * 先从数列中取出一个数作为key值; 将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边; 对左右两个小数列重复第二步,直至各区间只有1个数。 * @param a * @param l * @param r */public static void quickSort(int a[],int l,int r){    if(l>=r)        return;    int i = l; int j = r; int key = a[l];//选择第一个数为key    while(i<j){        while(i<j && a[j]>=key)//从右向左找第一个小于key的值            j--;        if(i<j){            a[i] = a[j];            i++;        }        while(i<j && a[i]<key)//从左向右找第一个大于key的值            i++;        if(i<j){            a[j] = a[i];            j--;        }    }    //i == j    a[i] = key; quickSort(a, l, i-1);//递归调用    quickSort(a, i+1, r);//递归调用}
辅助理解:挖坑填数初始时 i = 0; j = 9; key=72由于已经将a[0]中的数保存到key中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。从j开始向前找一个比key小的数。当j=8,符合条件,a[0] = a[8] ; i++ ; 将a[8]挖出再填到上一个坑a[0]中。这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于key的数,当i=3,符合条件,a[8] = a[3] ; j-- ; 将a[3]挖出再填到上一个坑中。此时 i = 3; j = 7; key=72再重复上面的步骤,先从后向前找,再从前向后找从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;从i开始向后找,当i=5时,由于i==j退出。此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将key填入a[5]。可以看出a[5]前面的数字都小于它,a[5]后面的数字都大于它。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了。
其他写法,这个更好理解一些

public void sort(int arr[],int low,int high) 

{ 

int l=low; 

int h=high; 

int povit=arr[low];  

while(l<h) { 

while(l<h&&arr[h]>=povit) h--; 

if(l<h){

int temp=arr[h]; 

arr[h]=arr[l]; 

arr[l]=temp; 

l++; 

 while(l<h&&arr[l]<=povit) l++;  

if(l<h){ 

int temp=arr[h]; 

arr[h]=arr[l]; 

arr[l]=temp; 

h--; 

} 

}  

if(l>low)sort(arr,low,l-1); 

if(h<high)sort(arr,l+1,high); 

}