经典排序算法(四)归并排序

自顶而下的归并排序

引言

自顶而下的归并排序 :(MergeSort)是建立在归并操作上的一种有效的排序算法,这也是应用高效算法设计中分治思想的最典型的一个例子。将已有序的子序列合并,得到完全有序的序列。

自顶而下归并算法核心步骤为 :

  • 分解
  • 合并

图片来源:排序算法之归并排序 ( C语言版 )

代码实现

#pragma once
#include<iostream>
#include<time.h>
using namespace std;
//自顶向下的归并排序Top-Down
class MergeSortT2D
{
    
    
private:
	int* aux;//辅助数组
	//合并两个有序数组
	void merge(int* arr, int lo, int mid, int hi)
	{
    
    
		//设置两个指针
		int i = lo, j = mid + 1;
		//拷贝区间元素
		for (int k = lo; k <= hi; ++k)
			aux[k] = arr[k];
		//合并两个有序线性表
		for (int k = lo; k <= hi; ++k)
		{
    
    
			if (i > mid) arr[k] = aux[j++];
			else if (j > hi) arr[k] = aux[i++];
			else if (aux[i] < aux[j]) arr[k] = aux[i++];
			else arr[k] = aux[j++];
		}
	}
	//排序
	void sort(int* arr, int lo, int hi)
	{
    
    
		if (hi <= lo) return;
		int mid = (lo + hi) / 2;
		sort(arr, lo, mid);
		sort(arr, mid + 1, hi);
		merge(arr, lo, mid, hi);
	}
	
public:
	MergeSortT2D(int* arr, int length)
	{
    
    
		//初始化辅助数组
		aux = new int[length] {
    
    };
		//排序过程计时
		clock_t beg = clock();
		sort(arr, 0, length - 1);
		clock_t end = clock();
		//直接输出排序耗时
		cout << "time is " << end - beg << "ms" << endl;
	}
};

自底向上的归并排序

实现归并排序的另一种方式是先归并那些微型数组,然后再成对归并得到的子数组,如此这般,直到我们将整个数组归并在一起。这种实现方法比标准递归方法所需要的代码量更少。

代码实现

#pragma once
#include<iostream>
#include<time.h>
#include<math.h>
using namespace std;
//自底向上的归并算法Down-Top
class MergeSortD2T
{
    
    
private:
	int* aux;//辅助数组
	//合并两个有序序列
	void merge(int* arr, int lo, int mid, int hi)
	{
    
    
		//设置两个指针
		int i = lo, j = mid + 1;
		//拷贝区间元素
		for (int k = lo; k <= hi; ++k)
			aux[k] = arr[k];
		//合并两个有序线性表
		for (int k = lo; k <= hi; ++k)
		{
    
    
			if (i > mid) arr[k] = aux[j++];
			else if (j > hi) arr[k] = aux[i++];
			else if (aux[i] < aux[j]) arr[k] = aux[i++];
			else arr[k] = aux[j++];
		}
	}
	//排序
	void sort(int* arr, int length)
	{
    
    
		for (int sz = 1; sz < length; sz = 2 * sz)
			for (int lo = 0; lo < length-sz; lo += 2 * sz)
			{
    
    
				int mid = lo + sz - 1;
				int hi = fmin((lo + 2 * sz - 1), length - 1);
				merge(arr, lo, mid, hi);
			}
				
	}

public:
	MergeSortD2T(int* arr, int length)
	{
    
    
		//初始化辅助数组
		aux = new int[length] {
    
    };
		//排序过程计时
		clock_t beg = clock();
		sort(arr, length);
		clock_t end = clock();
		//直接输出排序耗时
		cout << "time is " << end - beg << "ms" << endl;
	}
};

总结

归并算法是一种渐进最优的基于比较的排序算法。这句话的意思是归并排序在最坏情况下的比较次数和任意基于比较的排序算法的的最少比较次数都是~ n ∗ l o g n n*logn nlogn

  • 算法时间复杂度: O ( n ∗ l o g n ) O(n*logn) O(nlogn)
  • 算法空间复杂度: O ( n ) O(n) O(n)
  • 算法是否稳定:稳定
    算法稳定指的是序列通过算法排序后,比较值相同(key)的两个元素相对顺序不会发生改变
  • 算法适用范围:适用范围非常广泛,以至于Java的排序算法之一就是基于归并算法的思想实现的。

おすすめ

転載: blog.csdn.net/qq_42518941/article/details/115219237