快速排序


第一遍快速排序不会直接得到最终结果,只会把比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         

另外一种是基数不动  两个哨兵做指针


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值