交换排序之快速排序
2016-06-01 12:38
239 查看
应用交换排序思想的另一种经典排序算法是快速排序,快速排序的思想可以大致分成两大部分,一部分是利用分治策略的递归算法,另一部分是根据随机选择元素作为基准对整个数组进行的划分。算法先实现对数组进行划分,分成两个子数组,左边的子数组元素都比基准元素小,右边的子数组元素都比基准元素大。然后再对这两个子数组递归的进行划分,直到最后数组中只剩下一个元素。
给定一个数组如下
![](https://img-blog.csdn.net/20160602093041677)
选择第一个元素A[0]作为基准元素。X=A[0]。
定义两个变量i=0,j=A.length−1
![](https://img-blog.csdn.net/20160602093403934)
如果i<j,首先判断A[j]<
4000
/span>与基准X的大小关系,例子中有A[9]>X,则该元素比基准大,放在基准后面不动,只需将j作j−−运算向前移一位。接着判断A[j]=A[8]=48<72,小于基准的数应该放在前面,因此我们做A[i]=A[j]即A[0]=A[8]=48,(这个时候不需要交换A[i]与A[j],因为我们已经将A[0]作为基准保存起来了,即使A[0]元素被替换掉也没有关系)。然后将i向后移一位
![](https://img-blog.csdn.net/20160602110807853)
到这里,数组中元素A[j]=A[8]已经被放到了第一个位置,所以我们这时候不移动j下标的愿意是因为后面如果找到比基准大的元素还要放在这里。
,下标i指向A[1]=6这个元素,将6与基准72比较,有6<72,比72小的元素就是放在前面的,所以不加操作继续将下标i后移,到57这个元素时的情况与6相同,继续后移i,到i=3时,有A[i]=88>72,做操作A[j]=A[8]=A[i]=A[3],则有
![](https://img-blog.csdn.net/20160602112531908)
同样的,这里我们不再动下标i(因为这个元素已经被放到了后面,这个位置一会要放比基准小的本来在数组后面的元素)。向前移动下标j,到元素73位置处,有73>72,所以不做任何操作,再向前移动下标j到83位置处还是同样的不动,直到下标j到达位置42位置处,发现42<72,做操作A[i]=A[3]=A[j]=A[5]
![](https://img-blog.csdn.net/20160602113556703)
到这里之后同样的不再移动下标j(这个位置留着放前面过来的大于基准的元素),向后移动i到元素60的位置,因为60<72所以不做操作继续向后移动i,到这里之后有i=j=5不再满足i<j。此时将基准元素放在A[5]=72,完成划分并返回下标i,成功将数组划分成两个子数组。
Java实现的代码如下
上述代码可以进行简单的简化,但是为了清楚的表达整个算法的过程,我没有对其进行调整。这样可以分别对应每一部操作过程来更清楚的理解快速排序的过程。
输出结果
![](https://img-blog.csdn.net/20160602114455563)
LZ也是菜鸟一枚,正在努力学习中,如果哪里说的有错误的地方还劳烦大神指出来我会认真改正的哦
数组划分
我们使用一个例子来说明对数组的划分过程给定一个数组如下
选择第一个元素A[0]作为基准元素。X=A[0]。
定义两个变量i=0,j=A.length−1
如果i<j,首先判断A[j]<
4000
/span>与基准X的大小关系,例子中有A[9]>X,则该元素比基准大,放在基准后面不动,只需将j作j−−运算向前移一位。接着判断A[j]=A[8]=48<72,小于基准的数应该放在前面,因此我们做A[i]=A[j]即A[0]=A[8]=48,(这个时候不需要交换A[i]与A[j],因为我们已经将A[0]作为基准保存起来了,即使A[0]元素被替换掉也没有关系)。然后将i向后移一位
到这里,数组中元素A[j]=A[8]已经被放到了第一个位置,所以我们这时候不移动j下标的愿意是因为后面如果找到比基准大的元素还要放在这里。
,下标i指向A[1]=6这个元素,将6与基准72比较,有6<72,比72小的元素就是放在前面的,所以不加操作继续将下标i后移,到57这个元素时的情况与6相同,继续后移i,到i=3时,有A[i]=88>72,做操作A[j]=A[8]=A[i]=A[3],则有
同样的,这里我们不再动下标i(因为这个元素已经被放到了后面,这个位置一会要放比基准小的本来在数组后面的元素)。向前移动下标j,到元素73位置处,有73>72,所以不做任何操作,再向前移动下标j到83位置处还是同样的不动,直到下标j到达位置42位置处,发现42<72,做操作A[i]=A[3]=A[j]=A[5]
到这里之后同样的不再移动下标j(这个位置留着放前面过来的大于基准的元素),向后移动i到元素60的位置,因为60<72所以不做操作继续向后移动i,到这里之后有i=j=5不再满足i<j。此时将基准元素放在A[5]=72,完成划分并返回下标i,成功将数组划分成两个子数组。
递归调用
接下来有了对数组划分的算法之后,直接根据返回的两个子数组之间的划分下标两次递归调用这个数组划分算法,直到每个数组中都只剩下一个元素。Java实现的代码如下
public class QuickSort { public static void main(String []args){ int[]A={72,6,57,88,60,42,83,73,48,85}; quickSort(A,0,A.length-1); for(int i=0;i<A.length;i++){ System.out.println(A[i]); } } public static void quickSort(int[] A,int l,int r){ if(l<r){ int X=A[l]; int i=l; int j=r; while(i<j){ while(i<j && A[j]>=X){ j--; } if(i<j){ A[i]=A[j]; i++; } while(i<j && A[i]<=X){ i++; } if(i<j){ A[j]=A[i]; j--; } } A[i]=X; quickSort(A,l,i-1); quickSort(A,i+1,r); } } }
上述代码可以进行简单的简化,但是为了清楚的表达整个算法的过程,我没有对其进行调整。这样可以分别对应每一部操作过程来更清楚的理解快速排序的过程。
输出结果
LZ也是菜鸟一枚,正在努力学习中,如果哪里说的有错误的地方还劳烦大神指出来我会认真改正的哦
相关文章推荐
- 快速排序
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#快速排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析