Data structure algorithm learning summary - MOOC (7) Merge sort optimization (top-down, from small to large)

Data structure algorithm learning summary - MOOC (7) Merge sort optimization (top-down, from small to large)

1. Review

The previous section talked about merge sort and learned about the basic implementation of merge sort

This section will talk about two optimizations of merge sort

2. Ideas

1. When the merge sort is finally merged, the left and right sides are ordered. For an array such as [123467], first divide the left and right sides, 123|456, compare the middle element of mid=3 and mid+1=4, After dividing the first element on the right, it is found that 3 is smaller than 4, then there is no need to continue merging, that is, the optimization is achieved

2. Insertion sorting can be mixed in the merge process. We know that for a nearly ordered array, the performance of insertion sorting will be very good

3. Actual combat (key)

MergeSort.h

#ifndef MERGESORT_H_
#define MERGESORT_H_
#include <iostream>
/**
 * Merge the two parts [l...mid] and [mid+1...r]
 */
template<typename T>
void __merge(T arr[],int l,int mid,int r){
	//Temporary space, store the array of arr
	T aux[r-1+1];
	for(int i = l;i<=r;i++)
		aux [il] = arr [i];

	int i = l,j=mid+1;
	for(int k = l;k<=r;k++){
		//i>mid means that the array where i is located has been merged, and the array where j is located has not been merged, and needs to be merged again
		if(i > mid){
			arr[k] = aux[jl];
			j++;
		}else if(j > r){//j>r indicates that the array where j is located has been merged, and the array where i is located has not been merged, and needs to be merged again
			arr [k] = aux [il];
			i++;
		}else if(aux[il]<aux[jl]){
			arr [k] = aux [il];
			i++;
		}else{
			arr[k] = aux[jl];
			j++;
		}
	}

}

/**
 * Recursively use merge sort to sort the range of arr[l...r]
 */
template<typename T>
void __mergeSort(T arr[],int l,int r){
//	if(l >= r)
//		return;
	//Optimize 2
	if(l >= r-15){
		insertSort(arr,l,r);
		return;
	}
	int mid = (l+r)/2;
	__mergeSort(arr,l,mid);
	__mergeSort(arr,mid+1,r);
	//Optimize 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

Part of the test code

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;
}

operation result

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

Summarize

For nearly sorted arrays, the optimized merge sort has even higher performance than pure insertion sort

Comments and Suggestions

If you have any questions or suggestions, please leave a message to discuss


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325746795&siteId=291194637