您的位置:首页 > 编程语言 > Java开发

#算法排序(Java版)#快速排序

2014-07-27 21:09 190 查看
转自:白话经典算法系列之六 快速排序 快速搞定

快速排序

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤。因此我的对快速排序作了进一步的说明:挖坑填数+分治法

排序过程:

假设有一数组arr[]{72,6,57,88,60,42,83,73,48,85}进行快速排序。

下标











0

Flag=72

48

48

48

48

1

6

6

6

6

6

2

57

57

57

57

57

3

88

88

42

42

4

60

60

60

60

60

5

42

42

42

72

6

83

83

83

83

83

7

73

73

73

73

73

8

48

88

88

88

9

85

85

85

85

85

①初始时i=0;j=9;flag =arr[i]=72

由于已经将arr[0]中的数保存到flag中去,可以理解成在数组arr[0]上挖了一个坑,可以将其他数据填充到这里来。

②然后j=arr.length,j--,

寻找arr[j]<flag,刚好发现j=8时,即arr[8]=48小于flag,将48填充到上一个坑中,而此时相当于在arr[8]上挖了一个坑。

③之后再从右向左查找arr[i]>=flag.

不断重复步骤②、③,直至i>j,将flag填充到剩下的坑中。至此,一次选择排序就完成了。

对挖坑填数进行总结

1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。

2.j--由后向前找比它小的数,找到后挖出此数填前一个坑arr[i]中。

3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑arr[j]中。

4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

核心代码:

照着这个总结很容易实现挖坑填数的代码:

//返回调整后基准输的位置
public int adjustArray(int arr[],int left,int right){

int i = left,j = right;
int flag = arr[left];     //arr[left]即arr[i]就是第一个坑
while(i<j){
//从左向右找小于x的数来填arr[i]
while(i<j&&arr[j]>=flag){
j--;
}
if(i<j){
arr[i] = arr[j];//将arr[j]填到arr[i]中,arr[j]就形成一个新的坑
i++;
}
//从左向右找大于或等于x的数来填arr[j]
while(i<j&&arr[i]<flag){
i++;
}
if(i<j){
arr[j] = arr[i];//将arr[j]填到arr[i]中,arr[j]就形成一个新的坑
j--;
}
}
//退出时,i等于j,将flag填到这个坑中
arr[i] = flag;

return i;
}


再写分治算法的代码:
void quickSort(int arr[],int left,int right){
if(left<right){
int i = adjustArray(arr,left,right);//先成挖坑填数法调整arr[]
quickSort(arr,left,i-1);            //递归调用
quickSort(arr,i+1,right);
}
}


这样的代码显然不够简洁,对其组合如下:

public static void QuickSort(int arr[],int left,int right){
if(left<right){
int i = left,j = right,flag = arr[left];
while(i<j){
while(i<j&&arr[j]>=flag){// 从右向左找第一个小于flag的数
j--;
}
if(i<j){
arr[i++] = arr[j];
}
while(i<j&&arr[i]<flag){// 从左向右找第一个大于等于x的数
i++;
}
if(i<j){
arr[j--] = arr[i];
}
}
arr[i] = flag;
QuickSort(arr,left,i-1);   // 递归调用
QuickSort(arr,i+1,right);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: