快速排序的学习中遇到的问题(java)

   
   
package com.mmrx.quicksort;
/*快速排序*/
public class QuickSort {
/*主排序方法*/
public static void quickSort( int[] list ){
quickSort( list,0,list.length-1 );
}
/*辅助方法*/
private static void quickSort( int[] list,int first,int last ){
/*递归终止条件*/
if( last > first){
int pivotIndex = partition(list,first,last);
/*递归*/
quickSort( list,first,pivotIndex-1 );
quickSort( list,pivotIndex+1,last );
}
}
/*合并、寻找主元*/
private static int partition( int[] list,int first,int last ){
int pivot = list[first];
int high = last;
int low = first;
/*前后端遍历区间,找到前段大于主元,后端小于
* 主元的元素,交换位置*/
while( high > low ){
//
// while( high >low && list[low] <= pivot )
// low++;
//
// list[high] = list[low];//将比主元大的记录移动到高端
while( high >low && list[high] >= pivot )
high--;
list[low] = list[high]; //将比主元小的记录移动到低端
while( high >low && list[low] <= pivot )
low++;
list[high] = list[low];//将比主元大的记录移动到高端
}
list[low] = pivot;
return low;
}
}
问题1:在定位主元的方法partition中,两个while的顺序是否可以变?
   
   
/*前后端遍历区间,找到前段大于主元,后端小于
* 主元的元素,交换位置*/
while( high > low ){
//
// while( high >low && list[low] <= pivot )
// low++;
//
// list[high] = list[low];//将比主元大的记录移动到高端
while( high >low && list[high] >= pivot )
high--;
list[low] = list[high]; //将比主元小的记录移动到低端
while( high >low && list[low] <= pivot )
low++;
list[high] = list[low];//将比主元大的记录移动到高端
}
    由于在方法开头,我们将主元确定为序列第一个元素,之后的操作都是在序列本身上的赋值操作。
    在方法中保留的是主元的值,所以应该先将比主元小的记录移动到低端,再考虑比主元大的记录,即先考虑high,后考虑low。
    由代码可知,在high向前寻找的过程中,一旦发现元素值比pivot值小,就会将list[low]赋值为list[high]元素值,这样的话,list[low]原本的值就会丢失。但是最开始的list[low]已经被作为主元保留了下来,所以没有影响。
    如果代码是这样
   
   
while( high > low ){
while( high >low && list[low] <= pivot )
low++;
list[high] = list[low];//将比主元大的记录移动到高端
while( high >low && list[high] >= pivot )
high--;
list[low] = list[high]; //将比主元小的记录移动到低端
// while( high >low && list[low] <= pivot )
// low++;
//
// list[high] = list[low];//将比主元大的记录移动到高端
}
    首先进行的是low向后遍历数组,找到的low索引值应该是比主元大的数组元素的索引,此时,list[high]原本的值被list[low]值覆盖,彻底丢失,就会使得数组内容被改变,结果自然也就不正确了。

问题2:
  
  
list[low] = pivot;
return low;
返回值为何是low而不是high?
    有这么几种情况,第一种,在while中不发生值交换,那么主元的位置仍旧是原本的位置,即low(数组索引为0的位置);第二种,在while中发生值交换,执行完毕下面一句后不再发生值交换,结束循环。
   
   
list[low] = list[high]; //将比主元小的记录移动到低端
即low值被覆盖,此时list[low] == list[high],比主元小的值被向前移动了,但是high位置的元素空下了,而high位置的值应当为pivot,low向后挪动,high不变,执行完毕循环,有low == high,接下来执行问题2中的语句也就顺理成章了;第三种,执行完毕下面后不再发生值交换,结束循环,
   
   
list[high] = list[low];//将比主元大的记录移动到高端

从high位置开始向前遍历,找到比主元小的元素,执行 list[high] = list[low],比主元大的值被向后移动,low位置的元素空下了,high向前挪动,low的值不变,执行完毕循环,有low == high,执行问题2中的语句。

    实质上,只有两种可能,不发生值交换(low == 0)和发生值交换(最终肯定有low == high),而第一种可能就决定了返回值只能是low而不是high。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值