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

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>=最大长度时,不执行第二条递归。

这是必要的。

效果如图:



中间的数字间含有制表符的是排序的过程。

我刚才一直在推导一个问题,第一次左推导一直推导到第四行的时候,我遇到了一个问题,即当l=1的时候是怎么排0位置的值得数的?

————————————————我是分割符——————————————

然后我发现不用再进行左递归排序了。而是进行右递归排序,在右递归的左递归中会进行排序。

在推到到第七行的时候,会以第4和5位置之间分成两个排好序的数组。

又回到了上一种状态,最终左递归结束,进行右递归。

每次都是进行这么一个状态:

最左边和从右起小于游标的第一个数交换,交换后,左边的位置向右推一位。左推后的位置起找到大于游标的位置,和左腿后的位置交换。



效果如上图所示。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: