排序模板
目的在于复习常见的排序题型和实现方式。
快速排序
时间复杂度:最坏情况为\(O\left(n^{2}\right)\);平均时间复杂度为\(O\left(n \log _{2} n\right)\);
空间复杂度为:最坏情况\(O(n)\),当退化为冒泡排序;最好情况为\(O(\log_2{n})\),递归调用需要保存一些数据;
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
quicksort(nums,0,nums.size()-1);
return nums;
}
void quicksort(vector<int>& nums,int l,int r){
if(l>=r) return;
int i = l-1,j=r+1,x=nums[(l+r)>> 1];
while(i<j)
{
while(nums[++i] < x);
while(nums[--j]> x);
if(i<j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
quicksort(nums,l,j);
quicksort(nums,j+1,r);
}
};
堆排序
时间复杂度:buildMaxHeap为\(O(n)\);maxHeapify为\(O(\log_2{n})\);算法平均和最坏时间复杂度均为\(O(n\log_2{n})\);
空间复杂度为:\(O(1)\)
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
heapSort(nums);
return nums;
}
void heapSort(vector<int> &nums){
int len = (int)nums.size() -1;
buildMaxHeap(nums,len);
for(int i=len;i>=1;--i){
swap(nums[i],nums[0]);
len -=1;
maxHeapify(nums,0,len);
}
}
//创建最大堆
void buildMaxHeap(vector<int> & nums,int len){
//i从最后一个父节点开始调整
for(int i=len/2;i>=0;--i){
maxHeapify(nums,i,len);
}
}
//最大堆调整,将堆的末端子节点作调整,使得子节点永远小于父节点
void maxHeapify(vector<int> & nums,int i,int len){
for(;(i<<1) + 1 <= len;){
int lson = (i<<1) + 1;
int rson = (i<<1) + 2;
int large;
if(lson <= len && nums[lson] > nums[i]){
large = lson;
} else {
large = i;
}
if(rson <= len && nums[rson] > nums[large]){
large = rson;
}
if(large != i){
swap(nums[i],nums[large]);
i = large;
} else {
break;
}
}
}
void swap(int &i,int &j){
int t = i;
i = j;
j = t;
}
};
参考链接:
快速排序部分
[1] 快速排序时间复杂度分析 - ciwei的文章 - 知乎
[2] 快速排序模板 - 程序员阿sir的文章 - 知乎