看了网上很多人的快排,有些核心没讲到,导致我走了弯路。
遍历每一个基准数A的第一次替换绝对是替换A的位置
比A大的甩到右边,比A小的甩到左边
这话怎么理解呢,如果基准数位置的值没被填充,可能会导致数据丢失,在取完前四个基准数时会就会明白了
黄色填充框是待替换区
简单来说,快排是为每一个基准数据找其正确索引位置的过程
给出序列:3 ,44,38,5,47,15,36,26
基准数据从哪里开始其实没区别,反正要执行n-1次,那就将原数组a拷贝到数组b,遍历b数组,然后分别从数组的两端扫描数组,设两个指示标志:low指向起始位置,high指向末尾
第一遍:temp = 3;
接下去
无论从low指针开始还是high指针开始都行,
low指针从头开始遍历指向的元素arr[low],当arr[low]>temp时,low++;其他情况时停下。
high指针从尾开始遍历指向的元素arr[high],当arr[high]<temp时,high--;其他情况时停下。
当low == high时,就是基数的索引位置,用temp值替换
所以low == high == 0,3不动
第二遍:temp = 44;
low指针从头开始遍历指向的元素arr[low],当arr[low]>temp时,low++;其他情况时停下。
high指针从尾开始遍历指向的元素arr[high],当arr[high]<temp时,high--;其他情况时停下。
判断是low位置元素替换high元素,还是反之,除第一次外,后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。
俩个指针第一次停下,如图,面临是low指针元素替换high指针元素,还是反之。
第一次先看是low指针到基准数索引位置,还是high指针到基准数索引位置
基准数索引位置的值将被替换为26,替换完的low指针向后移动。high指针待替换
网上的某些文章永远是后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。
原索引位置的值已经转存到temp,如果第一遍不填充该位置会造成数据丢失,第四个基准数就会明白
俩个指针第二次停下,遵循后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。所以47替换26,high向前移,low不动待替换。
指针第三次停下,遵循。。所以36替换47,low向后移,high不动待替换。
(省略一万字)
第二遍结果
代码如下(java)
1.递归
public class QuickSort {
public static void QuickSort(int[] arr, int low, int high) {
if (low < high) {
int index = getIndex(arr,low,high);
QuickSort(arr,0,index - 1);
QuickSort(arr,index + 1,high);
}
}
public static int getIndex(int[] arr,int low,int high) {
int tmp = arr[low];
while (low < high) {
while (low < high && tmp <= arr[high]) {
high--;
}
arr[low] = arr[high];//第一次替换基准数的原索引位置
while (low < high && tmp >= arr[low]) {
low++;
}
arr[high] = arr[low];
}
arr[low] = tmp;
printArray(arr);
return low;
}
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
public static void main(String a[]) {
int[] array= new int[]{3,44,38,5,47,15,36,26};
// int[] array= new int[]{3,5,44,38,5,47,15,36,5,26};
QuickSort(array,0,array.length - 1);
}
}
2.非递归
public class QuickSort {
public static int[] QuickSort(int[] arr) {
int len = arr.length;
int[] tArr = arr.clone();
for (int i = 0; i < len - 1; i++) {//循环n-1次,0 or 1
int lowIdx = 0,highIdx = len - 1,temp;
temp = tArr[i];
boolean flag = true;//true为high,false为low
while(lowIdx != highIdx) {//low与high不相等
while(temp < arr[highIdx] && highIdx > lowIdx) {
highIdx--;
flag = true;
}
while(temp > arr[lowIdx] && highIdx > lowIdx) {
lowIdx++;
flag = false;
}
if (lowIdx != highIdx) {
if (lowIdx != i && highIdx != i) {//非第一次
if (flag) {
arr[lowIdx] = arr[highIdx];
lowIdx++;
flag = false;
} else {
arr[highIdx] = arr[lowIdx];
highIdx--;
flag = true;
}
}
if (lowIdx == i) {//第一次
arr[lowIdx] = arr[highIdx];
lowIdx++;
}
if (highIdx == i) {
arr[highIdx] = arr[lowIdx];
highIdx--;
}
}
}
arr[lowIdx] = temp;
printArray(arr);
}
return arr;
}
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
public static void main(String[] a) {
int[] array= new int[]{3,44,38,5,47,15,36,26};
// int[] array= new int[]{3,5,44,38,5,47,15,36,5,26};
QuickSort(array);
}
}
代码有点粗糙,但确实可行。