合并排序(分治法)

Posted outthinker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并排序(分治法)相关的知识,希望对你有一定的参考价值。

使用分治法进行合并排序,问题描述参见:https://www.cnblogs.com/jingmoxukong/p/4308823.html

算法核心:

//merge_sort.h
#ifndef MERGE_SORT_H
#define MERGE_SORT_H

template <class Type>
void MergeSort(Type a[], int n);

#include "merge_sort.template"

#endif

 

//merge_sort.template
template <class Type>
void MergeSort(Type a[], int n)
{
    Type *b = new Type[n];
    int s = 1;
    while (s < n)
    {
        MergePass(a, b, s, n);  //合并到数组b
        s += s;
        MergePass(b, a, s, n);  //合并到数组a
        s += s;
    }
    delete b;
}

template <class Type>
void MergePass(Type x[], Type y[], int s, int n)
{
    int i = 0;
    while (i <= n - s * 2)
    {
        Merge(x, y, i, i + s - 1, i + 2 * s - 1);  //合并大小为s的相邻两段子数组
        i += s * 2;
    }
    if (i + s < n)  //剩下的元素少于2s
        Merge(x, y, i, i + s - 1, n - 1);
    else for (int j = i; j <= n - 1; j++)
        y[j] = x[j];
}

template <class Type>
void Merge(Type c[], Type d[], int l, int m, int r)  //合并c[l:m]和c[m+1:r]到d[l:r],其中c[l:m]和c[m+1:r]都是已经经过升序排好的数组
{
    int i = l, j = m + 1, k = l;
    while ((i <= m) && (j <= r))
    {
        if (c[i] <= c[j])
            d[k++] = c[i++];
        else
            d[k++] = c[j++];
    }
    if (i > m)
        for (int q = j; q <= r; q++)
            d[k++] = c[q];
    else for (int q = i; q <= m; q++)
        d[k++] = c[q];
}

 

测试部分:

//main.cpp
#include <iostream>
#include "merge_sort.h"

using namespace std;

#define Type int  //定义Type类型

int main()
{
    int size;  //数组大小
    cout << "请输入数组大小: ";
    cin >> size;
    Type *a = new Type[size];  //定义一个数组
    cout << "请输入数组中元素:" << endl;
    for (int i = 0; i < size; i++)
    {
        cin >> a[i];
    }
    MergeSort(a, size);  //对数组进行升序排序
    cout << "输出合并排序后的数组: " << endl;
    for (int j = 0; j < size; j++)
    {
        cout << a[j] << "  ";
    }
    system("pause");
    delete a;
    return 0;
}

 

注意:

(1)由于这里使用了模板函数,一般地模板函数地声明和实现是不能分开的。(如果直接在main.cpp中加入extern void Mergesort(...)来调用其他.cpp文件中的MergeSort函数就回跳出“无法解析的外部符号,该函数已经在_main中被引用”的错误),如果想要在main.cpp中调用模板函数有两种方法:

a、将模板函数的声明和实现都放在同一个头文件中,然后在Main.cpp中进行include,但是这样子如果模板函数的的实现过长的话,会影响可读性,所以一般推荐下面的方法;

b、将模板函数的声明放在一个头文件中,模板函数的实现放在一个.template中,然后在main.cpp中include这个头文件就行了(但这种方法不具有普遍性,对不同的编译器版本可能并不通用)

c、将模板的声明放在一个头文件中,在一个cpp中写入该模板函数的实现(include模板的头文件),然后在main.cpp中include模板的.cpp文件推荐)(其实只是把.hpp中的声明和实现进行了拆分)

 

以上是关于合并排序(分治法)的主要内容,如果未能解决你的问题,请参考以下文章

合并排序(分治法)

基础算法 分治法之合并排序

排序——归并排序(分治法)

分治法

算法导论第2章 分治法与归并排序, 二分查找法

分治法