问题描述
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void quick_sort(vector<int> &a,int start,int end);
int partition(vector<int> &a,int end);
int main(){
vector<int> v = {7,6,5,4,3,2,1};
int n(7);
quick_sort(v,n);
for (auto& itr : v){
cout << itr << ' ';
}
return 0;
}
void quick_sort(vector<int> &a,int end){
if (start < end){
int index;
index = partition(a,start,end);
quick_sort(a,index - 1);
quick_sort(a,index,end);
}
}
int partition(vector<int> &a,int end){
int pivot,count(0);
pivot = a[end - 1];
for (int i = start; a[i] != pivot; i++){
if (a[i] > pivot){
a.insert(a.begin()+end,a[i]);
a.erase(a.begin() + i);
count++;
i--;
}
}
return end-count;
}
这里在分区函数中我使用了 STL 库中提供的插入和擦除函数。
分区函数的时间复杂度会大于O(n)吗(使用swaps的情况)?
据我所知,最坏的情况是当枢轴元素是最小元素时,所有 (n-1) 个元素都将被推到向量的末尾。
编辑:
int partition(vector<int> &a,int end){
int pivot;
pivot = end - 1;
for (int i = start; i < end; i++){
if (a[i] > a[pivot] && i < pivot){
swap(a[i],a[pivot]);
pivot = i;
}
else if (a[i] < a[pivot] && i > pivot){
swap(a[i],a[pivot]);
pivot = i;
}
}
return pivot + 1;
}
这个分区函数在 O(n) 时间内运行。
解决方法
在执行 end
后移动 insert
之后的每个元素,执行 i
后移动 erase
之后的每个元素。这个版本比交换差很多。使用 std::swap
,您只需触摸两个元素。
旁白:C++中的排序是traditionally done with iterators,不是索引,即
using iterator = std::vector<int>::iterator;
void quick_sort(iterator start,iterator end);
iterator partition(iterator start,iterator end);