jAVA_算法_快速排序
2016-07-18 16:32
417 查看
while循环中每运行一次,都会进行两次排序。
static void quicksort(int[] arr,int onle,int onri ){
int l=onle;
int h=onri;
int povit=arr[l];
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>onle)quicksort(arr,onle,l-1);//l位置固定
if(h<onri)quicksort(arr,l+1,onri);
}
}
第一次while是为了让l的位置大于h的情况,即想先排序一下。
第二次while中是为了从第二个参数开始,把对应的数组的下标往左边找第一个小于游标的值。游标的值为方法中第二个参数为数组的下标所对应的数组的值。
第三个While中是为了从左边往右边找第一个大于游标的值。
在第二次循环结束后有两种情况,一种是没找到合适的交换对象,导致h<l,就会导致下面所有的判断与循环都不执行。另外一种是找到h的位置,交换游标代表的数组中的值。L的位置向前移一位。再从L开始,包括L的位置找到比游标大的数组中的位置,然后交换。游标的值在两次交换中都没有受到影响。交换的是数组中元素的位置(两次)。
L的位置发生了两次变化,一次是做了个,向前推一位,因为发生了交换。第二次是为了寻找大于游标的元素在数组中的位置。
而h的位置也发生了两次变化,一次是从右往左走,找到第一个小于游标的元素的数组中的坐标。第二次是交换后的位置向前推一位。和L有异曲同工之妙。
在两个If中条件都必定为真,为什么不省去呢?这是为了做一次限定条件,当l=onle和h=onri时不执行,当onle>=onri时即1>0,1=1时不执行第一次递归。
同理,知h>=最大长度时,不执行第二条递归。
这是必要的。
效果如图:
![](http://img.blog.csdn.net/20160719084750911?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
中间的数字间含有制表符的是排序的过程。
我刚才一直在推导一个问题,第一次左推导一直推导到第四行的时候,我遇到了一个问题,即当l=1的时候是怎么排0位置的值得数的?
————————————————我是分割符——————————————
然后我发现不用再进行左递归排序了。而是进行右递归排序,在右递归的左递归中会进行排序。
在推到到第七行的时候,会以第4和5位置之间分成两个排好序的数组。
又回到了上一种状态,最终左递归结束,进行右递归。
每次都是进行这么一个状态:
最左边和从右起小于游标的第一个数交换,交换后,左边的位置向右推一位。左推后的位置起找到大于游标的位置,和左腿后的位置交换。
![](http://img.blog.csdn.net/20160719092912187?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
效果如上图所示。
static void quicksort(int[] arr,int onle,int onri ){
int l=onle;
int h=onri;
int povit=arr[l];
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>onle)quicksort(arr,onle,l-1);//l位置固定
if(h<onri)quicksort(arr,l+1,onri);
}
}
第一次while是为了让l的位置大于h的情况,即想先排序一下。
第二次while中是为了从第二个参数开始,把对应的数组的下标往左边找第一个小于游标的值。游标的值为方法中第二个参数为数组的下标所对应的数组的值。
第三个While中是为了从左边往右边找第一个大于游标的值。
在第二次循环结束后有两种情况,一种是没找到合适的交换对象,导致h<l,就会导致下面所有的判断与循环都不执行。另外一种是找到h的位置,交换游标代表的数组中的值。L的位置向前移一位。再从L开始,包括L的位置找到比游标大的数组中的位置,然后交换。游标的值在两次交换中都没有受到影响。交换的是数组中元素的位置(两次)。
L的位置发生了两次变化,一次是做了个,向前推一位,因为发生了交换。第二次是为了寻找大于游标的元素在数组中的位置。
而h的位置也发生了两次变化,一次是从右往左走,找到第一个小于游标的元素的数组中的坐标。第二次是交换后的位置向前推一位。和L有异曲同工之妙。
在两个If中条件都必定为真,为什么不省去呢?这是为了做一次限定条件,当l=onle和h=onri时不执行,当onle>=onri时即1>0,1=1时不执行第一次递归。
同理,知h>=最大长度时,不执行第二条递归。
这是必要的。
效果如图:
中间的数字间含有制表符的是排序的过程。
我刚才一直在推导一个问题,第一次左推导一直推导到第四行的时候,我遇到了一个问题,即当l=1的时候是怎么排0位置的值得数的?
————————————————我是分割符——————————————
然后我发现不用再进行左递归排序了。而是进行右递归排序,在右递归的左递归中会进行排序。
在推到到第七行的时候,会以第4和5位置之间分成两个排好序的数组。
又回到了上一种状态,最终左递归结束,进行右递归。
每次都是进行这么一个状态:
最左边和从右起小于游标的第一个数交换,交换后,左边的位置向右推一位。左推后的位置起找到大于游标的位置,和左腿后的位置交换。
效果如上图所示。
相关文章推荐
- Java 8 中的 Streams API 详解
- Think in java...
- spring技术框架基础知识二(静态)动态代理
- 【Java并发编程】并发之痛 Thread,Goroutine,Actor
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
- <java编程思想>(thing in java) 阅读笔记(第一章至第六章)
- springmvc框架原理的一些理解
- 关于Spring-mvc的机制以及Ioc、DI的理解
- 从基层容器类看万变不离其宗的JAVA继承体系
- 01-java的基本了解
- The Default Methods And Static Methods In Java Interface
- jdk各个版本
- 使用Eclipse和CMake构建项目
- Java 协变性 逆变性
- 用interrupt()中断Java线程
- IntelliJ安装JRebel热部署插件
- Spring基础—— Bean 的作用域
- Java List中的一个List选择选择移除方法
- Java Web 技术学习主线
- 多线程Java