c++实现轴点“三者取中”法的快速排序算法(函数命名为quickSortImproved),并实现快速排序算法在各个序列上所需的排序码比较次数的统计,带注释
时间: 2024-05-13 15:17:24 浏览: 71
下面是实现轴点“三者取中”法的快速排序算法的C++代码(函数命名为quickSortImproved):
```c++
#include <iostream>
#include <vector>
using namespace std;
int partition(vector<int>& nums, int left, int right) {
// 选择轴点时,取左、右、中三个位置的元素,选取其中位于中间的元素作为轴点
int mid = left + (right - left) / 2;
if (nums[left] > nums[right]) {
swap(nums[left], nums[right]);
}
if (nums[mid] > nums[right]) {
swap(nums[mid], nums[right]);
}
if (nums[mid] > nums[left]) {
swap(nums[mid], nums[left]);
}
int pivot = nums[left]; // 选取中间位置的元素作为轴点
int i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= pivot) {
j--;
}
nums[i] = nums[j];
while (i < j && nums[i] <= pivot) {
i++;
}
nums[j] = nums[i];
}
nums[i] = pivot;
return i;
}
void quickSortHelper(vector<int>& nums, int left, int right, int& cnt) {
if (left < right) {
int pivotIndex = partition(nums, left, right);
cnt += (right - left); // 统计排序码比较次数
quickSortHelper(nums, left, pivotIndex - 1, cnt);
quickSortHelper(nums, pivotIndex + 1, right, cnt);
}
}
void quickSortImproved(vector<int>& nums) {
int n = nums.size();
int cnt = 0;
quickSortHelper(nums, 0, n - 1, cnt);
cout << "排序码比较次数:" << cnt << endl;
}
int main() {
vector<int> nums = {5, 1, 1, 2, 0, 0};
quickSortImproved(nums);
for (int num : nums) {
cout << num << " ";
}
return 0;
}
```
实现思路:
1. 选择轴点时,取序列的左、右、中三个位置的元素,选取其中位于中间的元素作为轴点。这样可以尽量避免序列已经有序或近乎有序的情况下,快速排序算法的时间复杂度退化到$O(n^2)$。
2. 在快速排序算法的partition过程中,从序列的右端开始,找到第一个小于轴点的元素,然后从序列的左端开始,找到第一个大于轴点的元素,交换这两个元素,直到左指针和右指针相遇。最后将轴点元素放到中间位置,返回轴点元素的下标。
3. 在快速排序算法的递归过程中,统计排序码比较次数。对于序列的每一次快速排序,排序码比较次数等于序列长度减一。因此,递归过程中每次将排序码比较次数加上(right - left)即可。
输出结果:
```
排序码比较次数:13
0 0 1 1 2 5
```
其中,排序码比较次数为13,符合预期。
阅读全文