Data structure algorithm learning summary - MOOC (8) Merge sort (bottom-up, from small to large)

Data structure algorithm learning summary - MOOC (8) Merge sort (bottom-up, from small to large)

1. Review

In the previous section, we talked about the optimization of top-down recursive merge sort. We can merge from bottom to top without using recursion.

2. Actual combat

main.cpp

#include <iostream>
#include "SortTestHelper.h"
#include "MergeSort.h"
#include "InsertSort.h"

using namespace std;

/**
 * Bottom-up merge
 */
template<typename T>
void mergeSortBU(T arr[],int n){
	for (int sz = 1; sz <= n; sz + = sz) {
		for(int i = 0;i + sz < n;i+=sz+sz){
			//Optimization 1, insertion sort for nearly ordered arrays
			if(i >= i+sz+sz-1-15){
				insertSort(arr,i,i+sz+sz-1);
			}
			//Optimize 2, like 2 3|4 5, the left and right are ordered, 3 is smaller than 4, then the entire array is from small to large, no need to sort
			if(arr[i+sz-1] > arr[i+sz-1+1]){
			__merge (arr, i, i + sz-1, min (i + sz + sz-1, n-1));
			}
		}
	}
}

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

	SortTestHelper::testSort("Merge Sort BU:",mergeSortBU,arr,n);
	SortTestHelper::testSort("Merge Sort:",mergeSort,arr1,n);
	delete[] arr;
	return 0;
}

MergeSort.h

#ifndef MERGESORT_H_
#define MERGESORT_H_
#include <iostream>
#include "InsertSort.h"
/**
 * 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

operation result

Merge Sort BU:: 0.007s

Merge Sort: : 0.005s

Summarize

Bottom-up merging is similar to top-down merging. Strictly speaking, top-down efficiency is better.

One advantage of bottom-up merging is that it can sort the linked list. Interested students can study it by themselves.

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=325746651&siteId=291194637