快速排序是一种不稳定的排序,时间复杂度为O(nlogn),但在数组近似有序的情况下,时间复杂度会退化成O(n*n)。
基本思想:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
算法思路:
1.先从队尾开始向前扫描且当low < high时,如果a[high] >= tmp,则high–;但如果a[high] < tmp,则将high的值赋值给low,即arr[low] = a[high]。同时要转换数组扫描的方式,即需要从队首开始向队尾进行扫描了;
2.同理,当从队首开始向队尾进行扫描时,如果a[low] <= tmp,则low++;但如果a[low] > tmp,则将low位置的值赋值给high位置,即arr[high] = arr[low],同时将数组扫描方式换为由队尾向队首进行扫描;
3.不断重复1和2,直到low >= high时(其实是low=high),low或high的位置就是该基准数据在数组中的正确索引位置,返回该索引。
核心代码如下:
#include <iostream>
using namespace std;
int __partition(int arr[], int l, int r){
int tmp = arr[l];
int low = l;
int high = r;
while (low < high) {
//当队尾的元素大于等于基准数据tmp时,向前挪动high指针
while (low < high && arr[high] >= tmp) {
high--;
}
//如果队尾元素小于等于tmp了,需要将其赋值给low
arr[low] = arr[high];
//当队首元素小于等于tmp时,向前挪动low指针
while (low < high && arr[low] <= tmp) {
low++;
}
//当队首元素大于tmp时,需要将其赋值给high
arr[high] = arr[low];
}
//跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
//由原理部分可以很清楚的知道此时low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
arr[low] = tmp;
return low; //返回tmp的正确位置
}
void __quicksort(int arr[], int l, int r){
if(l >= r)
return;
int p = __partition(arr, l, r);
__quicksort(arr, l, p - 1);
__quicksort(arr, p + 1, r);
}
void quicksort(int arr[], int n){
__quicksort(arr, 0, n - 1);
}
int main(){
int arr[] = {1,4,7,5,9,6,8,3,2};
int length = sizeof(arr) / sizeof(arr[0]);
quicksort(arr, length);
for(int i = 0; i < length; i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}