zoukankan      html  css  js  c++  java
  • 合并排序(分治法)

    使用分治法进行合并排序,问题描述参见: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中的声明和实现进行了拆分)

  • 相关阅读:
    μC/OS-III---I笔记5---多值信号量
    μC/OS-III---I笔记4---软件定时器
    μC/OS-III---I笔记3---时间管理
    μC/OS-III---I笔记2---实钟节拍
    μC/OS-III---I笔记1---概述
    Cortex-M系列内核 启动文件分析
    C语言中函数的调用方式
    const,volatile,static,typdef,几个关键字辨析和理解
    java注解细节
    java枚举细节
  • 原文地址:https://www.cnblogs.com/zf-blog/p/8340862.html
Copyright © 2011-2022 走看看