归并排序包括两部分:将数组分成两部分排序;将排好序的两部分合并
void mergeSort(vector<int>& nums, int l, int r){
if (l >= r) return ;//终止条件
int mid = l + (r - l) / 2;
mergeSort(nums, l, mid);
mergeSort(nums, mid + 1, r);//归
merge(nums, l, r);//并
}void merge(vector<int>& nums, int l, int r){
int mid = l + (r - l) / 2;
vector<int> lpart(nums.begin()+l, nums.begin()+mid+1);//借助辅助空间
vector<int> rpart(nums.begin() + mid+1, nums.begin() + r+1);
vector<int>::iterator liter = lpart.begin();
vector<int>::iterator riter = rpart.begin();
for (int i = l; i <= r; i++){
if (liter != lpart.end() && riter != rpart.end()){
if (*liter < *riter){
nums[i] = *liter;
liter++;
}
else{
nums[i] = *riter;
riter++;
}
}else if (liter != lpart.end()){
nums[i] = *liter;
liter++;
}else if (riter != rpart.end()){
nums[i] = *riter;
riter++;
}
}
}
时间复杂度
每次递归将数组一分为二,递归层数为lgn,每层递归都需要遍历一次n个元素,所以为O(nlgn)
空间复杂度
空间上的消耗主要在合并数组时,先把元素放在辅助空间经过比较再放在原数组中
第一层递归需要两个n/2的数组,辅助空间为n
第二层递归需要两个n/4的数组,辅助空间为n/2
.......
第lgn-1层递归需要两个1的数组,辅助空间为2
第lgn层递归触发终止条件返回
所以空间复杂度为O(n)
延伸
如果想达到O(1)的空间复杂度,不使用辅助空间,就地排序,使用快排可以实现,但是时间复杂度达到O(n²),u can't have both kind of old story