第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。
主要两种 第一种挖坑法 百度百科这个很详细了
假设用户输入了如下数组:
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
6
|
2
|
7
|
3
|
8
|
9
|
创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(
赋值为第一个数据的值)。
我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始,从右往左找,不断递减变量j的值,我们找到第一个下标3的数据比6小,于是把数据3移到下标0的位置,把下标0的数据6移到下标3,完成第一次比较:
下标
|
0
|
1
|
2
| 3 |
4
|
5
|
数据
|
3
|
2
|
7
|
6
|
8
|
9
|
i=0 j=3 k=6
接着,开始第二次比较,这次要变成找比k大的了,而且要从前往后找了。递加变量i,发现下标2的数据是第一个比k大的,于是用下标2的数据7和j指向的下标3的数据的6做交换,数据状态变成下表:
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
i=2 j=3 k=6
称上面两次比较为一个循环。
接着,再递减变量j,不断重复进行上面的循环比较。
在本例中,我们进行一次循环,就发现i和j“碰头”了:他们都指向了下标2。于是,第一遍比较结束。得到结果如下,凡是k(=6)左边的数都比它小,凡是k右边的数都比它大:
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。
然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止。
对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
照着这个总结很容易实现挖坑填数的代码:
1 package Sorting; 2 3 public class QuickSorting { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 int arr[]={1,5,6,84,15,26,355,26,35,36,45,-5,36,45,18,4,44,58}; 8 int brr[]={1,5,6,84,15,26,35,36,45,18,4,44,58,555,63,78,98,15,0,-5,-8}; 9 QuickSort qs=new QuickSort(); 10 qs.sort1(0, arr.length-1,arr); 11 12 qs.sort2(0, brr.length-1,brr); 13 14 for(int e:arr){ 15 System.out.print(e+" "); 16 } 17 System.out.println(); 18 System.out.println("**********************************"); 19 for(int e:brr){ 20 System.out.print(e+" "); 21 } 22 } 23 } 24 25 class QuickSort { 26 27 // 1.挖坑填数+分治法 ****************** 28 29 public void sort1(int L,int R,int s[]){ 30 if(L<R){ 31 int i=L,j=R,x=s[L]; 32 while(i<j){ 33 //从右到左找第一个比x小的数 填坑 34 while(i<j && s[j]>=x){ 35 j--; } 36 37 if(i<j){ 38 s[i]=s[j]; //将s[j]填到s[i]中,s[j]就形成了一个新的坑 39 i++; 40 } 41 42 43 //从左到右找到第一个数比x大的数填最近出现的坑 44 while(i<j && s[i]<x){ 45 i++; } 46 47 if(i<j){ 48 s[j]=s[i]; //将s[i]填到s[j]中,s[i]就形成了一个新的坑 49 j--; 50 } 51 } 52 s[i]=x; 53 sort1(L,i-1,s); //递归调用 54 sort1(i+1,R,s); 55 } 56 } 57 58
另外一种是基数不动 两个哨兵做指针