先上图,看图比较容易理解:( 一次 快排步骤演示)
快排关键——分割数组
以上演示给出了快排的关键:分割数组
将所给的数组以pivot分为两个数组
- 左边的数组元素都小于等于pivot
- 右边的数组元素都大于等于pivot
注:
其中的橙色连线表示数组元素交换
蓝色连线表示数组元素比较大小
分析过程
1.快速排序中最重要的一个环节就是分割数组,将给定的数组以pivot为界分为左右两个子数组, 左边的数组元素都小于pivot,右边的数组元素都大于pivot。
2.在进行分割操作时,首先选择一个比较的基准元素,为方便我这里选择数组最后一个元素为pivot。
3.然后开始元素比较和交换;这里面需要用到两个数组下标i和j,比较和交换的规则为如下:(看上图演示辅助理解)
low: 最左边数组下标 high:左右边数组下标
int i= low;
for(j = low;j<= high-1; j++){
if ( arr[j] < pivot) {
Swap(arr[i] , arr[j]);
i++;
}
}
Swap(arr[i], pivot);
4.在第一次分割操作后,返回pivot的位置,然后我们需要对得到的两个数组进行相同分割,最后我们会得到一个有序的数组 (还是个递归问题)
5.当分割操作到最后,子数组足够小(low=high),我们就将所有的子数组元素都已经排好序了,那么元素组也就是排好序的了。就结束运行。
代码实现(C++)
#include <stdio.h>
#include <iostream>
using namespace std;
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int arr[], int low, int high) {
int pivot = arr[high];
cout<<"pivot:"<<pivot<<endl;
int i = low ;
for (int j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
swap(&arr[i], &arr[j]);
i++;
}
}
swap(&arr[i], &arr[high]);
return i;
}
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void printArray(int arr[], int size) {
int i;
for (i = 0; i < size; i++) cout << arr[i] << " ";
cout << endl;
}
int main() {
int arr[] = {10, 7, 82, 9, 13, 5, 2, 34, 54, 3, 26, 6, 37, 6, 48, 11};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Prepare Sorted array: \n";
printArray(arr, n);
quickSort(arr, 0, n - 1);
cout << "Sorted array: \n";
printArray(arr, n);
return 0;
}
代码关键就在partition()函数,多看几遍,然后根据一文章开头给的演示图一起理解。就可以掌握快排的诀窍了。
运行结果