数据结构算法学习总结-慕课网(七)归并排序优化(自顶向下,从小到大)

数据结构算法学习总结-慕课网(七)归并排序优化(自顶向下,从小到大)

1.回顾

上一节讲到归并排序,了解了归并排序的基本实现

这一节将讲归并排序的两个优化

2.思路

1.归并排序最后归并的时候,左边和右边都是有序的,对于[123467]这样的数组,首先划分开左右两边,123|456,比较mid=3中间的元素和mid+1=4,划分之后右边第一个元素,发现3比4小,那么就不需要继续归并,即实现了优化

2.可以在归并过程中,混合插入排序,我们知道对于一个近乎有序的数组,插入排序的性能将会很好

3.实战(关键)

MergeSort.h

#ifndef MERGESORT_H_
#define MERGESORT_H_
#include <iostream>
/**
 * 将[l...mid]和[mid+1...r]两部分进行归并
 */
template<typename T>
void __merge(T arr[],int l,int mid,int r){
	//临时空间,存贮arr的数组
	T aux[r-l+1];
	for(int i = l;i<=r;i++)
		aux[i-l]=arr[i];

	int i = l,j=mid+1;
	for(int k = l;k<=r;k++){
		//i>mid表示i所在数组已经归并完,j所在的数组没有归并完,还需要归并一次
		if(i > mid){
			arr[k] = aux[j-l];
			j++;
		}else if(j > r){//j>r表示j所在数组已经归并完,i所在的数组没有归并完,还需要归并一次
			arr[k] = aux[i-l];
			i++;
		}else if(aux[i-l]<aux[j-l]){
			arr[k] = aux[i-l];
			i++;
		}else{
			arr[k] = aux[j-l];
			j++;
		}
	}

}

/**
 * 递归使用归并排序,对arr[l...r]的范围排序
 */
template<typename T>
void __mergeSort(T arr[],int l,int r){
//	if(l >= r)
//		return;
	//优化2
	if(l >= r-15){
		insertSort(arr,l,r);
		return;
	}
	int mid = (l+r)/2;
	__mergeSort(arr,l,mid);
	__mergeSort(arr,mid+1,r);
	//优化1
	if(arr[mid] > arr[mid+1]){
		__merge(arr,l,mid,r);
	}
}

template<typename T>
void mergeSort(T arr[],int n){
	__mergeSort(arr,0,n-1);
}
#endif

部分测试代码

int main(){
	int n = 100000;
	int* arr = SortTestHelper::generateNearlyOrderedArray(n,100);
	int* arr1 = SortTestHelper::copyArray(arr,n);

	SortTestHelper::testSort("Merge Sort:",mergeSort,arr,n);
	SortTestHelper::testSort("insert Sort:",insertSort,arr1,n);

	delete[] arr;
	delete[] arr1;
	return 0;
}

运行结果

Merge Sort: : 0.003s
insert Sort: : 0.007s

总结

对于近乎有序的数组,优化后的归并排序,性能甚至比单纯的插入排序更高

意见与建议

如果博友有任何问题或者建议,欢迎留言讨论


猜你喜欢

转载自blog.csdn.net/libinbin147256369/article/details/79972156
今日推荐