快速排序是一种高效的排序算法,其基本思想是通过一个基准值将数组分成两部分,一部分所有元素都比基准值小,另一部分所有元素都比基准值大,然后对这两部分递归进行快速排序。不过一直以来写递归算法我都感觉是一个很头疼的问题,索性今天好好写一下快排的算法。
①首先,给定一个乱序的数组,找到其第一个位置的元素first(或者最后一个元素end)。
②将数组中除first(end)以外的所有元素与first(end)进行对比。注意这时遍历要取fisrt(end)的反方向,即取第一个元素做first的话要从后往前遍历,反之从前往后。(这样做的目的是为了一会交换元素时互不干扰!)
③进行判断,如果是比当前值更大的数则替换当前数组的末端,并将末端索引往前移动1格。
这样在遍历完成之后,即可以将除first(end)之外的所有比其大(小)的元素都放在后面。 ④最后因为这个选取的元素还在first(end)的位置上,因此,再将其与当前的末端(首端)进行调换,然后提取这个索引。
在得到这个索引之后,就固定下来了这个数字在数组中的位置,于是可以用它将前面和后面分别划分成两个乱序数组重复上面的操作即可。
附上代码:
#include<iostream>
#include<vector>
// 打印数组函数
void printArray(const std::vector<int>& arr) {
for (int num : arr)
std::cout << num << " ";
std::cout << std::endl;
}
int partition(std::vector<int>&arr, int low, int high) {
int first = arr[low]; //记录的是当前自己的第一个值
//从后往前遍历除自身以外的所有数字
for (size_t i = high; i > low; i--) {
if (arr[i] >= first) { //比第一个值大的换到后面去!!!
std::swap(arr[i], arr[high]); //将当前的值和未经过固定的最后一个交换。
high--; //因为后面存了一个,所以索引往前推。
}
}
//遍历完除自身以外的所有比它大的数字之后,它自己就是最大的了
std::swap(arr[low], arr[high]);
return high;
}
void quickSort(std::vector<int>&arr, int low, int high) {
if (low < high) {
int q = partition(arr, low, high); //partition:隔板
//递归求取小的和大的
quickSort(arr, low, q - 1);
quickSort(arr, q + 1, high);
}
}
// 主函数
int main() {
std::vector<int> arr;
int n;
std::cout << "请输入数组的大小: ";
std::cin >> n;
std::cout << "请输入数组的元素: ";
for (int i = 0; i < n; ++i) {
int element;
std::cin >> element;
arr.push_back(element);
}
std::cout << "给定的数组: ";
printArray(arr);
// 调用快排
quickSort(arr, 0, arr.size() - 1);
std::cout << "排序后的数组: ";
printArray(arr);
return 0;
}