归并排序C++实现

405 阅读1分钟

归并排序包括两部分:将数组分成两部分排序;将排好序的两部分合并

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