合并排序(分治法)
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中的声明和实现进行了拆分)
以上是关于合并排序(分治法)的主要内容,如果未能解决你的问题,请参考以下文章