在算法设计中应注意的几点;
1,在快速排序中对于划分好的左右两边需要采用递归算法,直至递归的规模为1,对于左侧的数据,可以是一直以0为基准的,而对于右侧的数据区,它的起始位置是动态变化,因此需要进行索引的备份,已实现对右侧数据的递归排序进行成功实现。这也是起始最难以理解的部分,不清晰为什么需要对left,right,进行赋值给变量i和j。
2,注重判断条件,已实现不必要的交换,尽量减少对内存资源的损耗。在从右至左寻找小于基准值和从左至右寻找大于基准值时,若指针指向同一索引时,此时对于同一元素是没有必要进行交换。
3.一趟快速排序之后,此时的i和j指向数组的同一元素(此刻的元素肯定是小于等于基准数的,(第一种可能从右侧到左侧尝试搜索小于基准数,要么找到,要么i,j相遇,等于基准数)),而它的左侧都是小于这一元素右侧是大于该元素的,但此时必须进行该元素和基准数据的交换,而不能直接将该元素归并至左侧进行递归,而是进行数据的交换,例如左侧为4,1,2,3,3是基准数,此时将永远不能对其排序成功。
代码如下:
import java.util.Arrays;
public class quickSort {
public static void quick(int[] a ,int left,int right) {
if(left>=right) {
return ;
}
int i =left;
int j =right;
//必须是left,而不能是0,因为右侧递归调用该方法时,left处于动态变化
int temp = a[left];
while(i<j) {
while(i!=j) {
//从右至左尝试搜索小于基准数的索引
while(i<j&&a[j]>=temp) {
j--;
}
//从左至右尝试搜索大于基准数的索引
while(i<j&&a[i]<=temp) {
i++;
}
if(j!=i) {
int temp1 = a[j];
a[j] = a[i];
a[i]= temp1;
}
}
a[left] = a[j];
a[j]=temp;
System.out.println(Arrays.toString(a));
//递归进行排序左侧
quick(a, 0, i-1);
//递归排序右侧
quick(a, i+1, right);
}
//循环结束之后,i和j必指向同一索引,将指向同一索引的值与基准值交换,保证左侧为小于基准值。右侧为大于基准值
}
public static void main(String[] args) {
int[] a = {1,5,7,12,45,2,-1,8};
System.out.println(Arrays.toString(a));
quick(a, 0, a.length-1);
}
}