在对数组进行排序算法时,如果我使用多个下标进行元素交换的时候,可能会出错。
以下面的直接选择排序(排列升序)为例:
public static void selectSort1(int[] arr){
int left=0;
int right=arr.length-1;
while(left<right){
int minIndex=left;
int maxIndex=left;
for (int i = left+1; i <=right ; i++) {
if(arr[minIndex]>arr[i]) minIndex=i;
if(arr[maxIndex]<arr[i]) maxIndex=i;
}
swap(minIndex,left,arr);
swap(maxIndex,right,arr);
left++;
right--;
}
}
直接选择排序逻辑很简单,这上面的代码逻辑好像也可以,但是我们给到这样一个测试用例:
int[] arr = new int[]{11,6,10,8,7};
执行结果:
这是怎么一回事?
其实就是元素交换,但是下标却没有跟着换导致的。
第一次while循环中的for循环执行完之后,minIndex=left+1
而maxIndex=left--->没有变。
for循环之后,就要对arr[minInex]与arr[left]交换。
一旦交换完之后,arr[left]的值就变成了arr[minIndex]的值了。
此时,arr[maxIndex](也就是arr[left])就不在是最大值了。
修改也很简单:
public static void selectSort1(int[] arr){
int left=0;
int right=arr.length-1;
while(left<right){
int minIndex=left;
int maxIndex=left;
for (int i = left+1; i <=right ; i++) {
if(arr[minIndex]>arr[i]) minIndex=i;
if(arr[maxIndex]<arr[i]) maxIndex=i;
}
swap(minIndex,left,arr);//这里交换完之后
if(maxIndex==left){//检查maxIndex所指向的元素是否会被交换
maxIndex=minIndex;//交换,那么指向原来的数字
}
swap(maxIndex,right,arr);
left++;
right--;
}
}