合并排序(分治法)

使用分治法进行合并排序,问题描述参见: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这个头文件就行了

原文地址:https://www.cnblogs.com/zf-blog/p/8340862.html

时间: 2024-10-14 14:20:16

合并排序(分治法)的相关文章

算法实验:分治法合并排序(C++)

这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来. 我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别.但是下面的报告是我放到vs里面测试过的,可以直接用,不影响. 第一部分:(解析) 题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组. 题目分析: 需要随机产生一个整数数组: 采用的算法是合并排序,也就是用归并排序: 输出排序后的数组. 随机产生一个整数数组:这个问题首先想到的是用rand()函

分治法-合并排序和快速排序

分治法是按照以下方案工作的: 将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模 对这些较小的实例求解(一般使用递归方法,但在问题规模足够小的时候,有时会利用另一种算法以提高效率) 如果必要的话,合并较小问题的解,以得到原始问题的解 分治法的流程: 4.1 合并排序 合并排序是成功应用分治技术的一个完美例子(书上说的). 对于一个需要排序的数组,合并排序把它一分为二,并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组. 代码实现: /** * 合并排序 * @au

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

思想: 合并排序算法的分治策略是将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合. 1 #include <stdio.h> 2 3 void merge(int a[],int p,int q,int r) 4 { 5 int n1=q-p+1,n2=r-q; 6 int b1[n1]; 7 int b2[n2]; 8 int i=0,j=0,temp1=p,temp2=q; 9 while(p<=q) 10 { 11

python实现分治法排序

# -*- coding: utf-8 -*- """ Created on Wed May 14 16:14:50 2014 @author: lifeix """ def merge(a, start, mid, end): if start == end: return a if mid == 0: return a temp1 = a[start:mid] m1 = len(temp1)/2 print temp1,'----',m1 n

分治法排序之归并排序

使用分治法的两路合并排序算法: 将待排序的元素序列一分为二,得到长度基本相等的两个子序列,分别排序. 如果子序列较长,还可继续细分,直到子序列的长度不超过1为止. 当分解所得的子序列已排列有序时,将两个有序子序列合并成一个有序子序列,得到原问题的解. 合并方法: 比较两序列中的最小值,输出其中较小者,然后重复此过程,直到其中一个队列为空时, 如果另一个队列还有元素没有输出,则将剩余元素依次输出. #include<stdio.h>#define N 100int merge(int *a, i

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

在写归并排序之前,首先谈一谈分治的思想, 所谓分治:就是将一个比较复杂的问题分解为若干个规模较小的但是类似原问题的子问题,(解决)递归地求解这些这些子问题,再合并这些子问题的解来求解原问题 可分为三步: 分解:将原问题分解为若干个规模较小的但是类似原问题的子问题 求解:递归地求解这些这些子问题,然而若子问题规模足够小,可直接求解 合并:合并这些子问题的解来求解原问题 接下来,终于可以写归并排序了 分解:将一个有N个数的数列分解为2个分别有n/2个数的2个子数列 求解:使用归并排序递归地分别排序两

专题:分治法

分治法(Divide and Conquer) 作为五大算法之一的分治法,可算是最早接触的一种算法.分治法,与其说是一种算法,不如将其称为策略来的更贴切一些.算法的思想就是将大问题分成小问题,并解决小问题之后合并起来生成大问题的解. 分治法的精髓: 分--将问题分解为规模更小的子问题: 治--将这些规模更小的子问题逐个击破: 合--将已解决的子问题合并,最终得出“母”问题的解: 分治法的作用,自然是让程序更加快速地处理问题.比如一个n的问题分解成两个n/2的问题,并由两个人来完成,效率就会快一些

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

分治法与递归编程步骤

分治法是一种很强大的算法设计方法.基本思想是:将原问题分解为几个规模小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 在分治策略中,递归地求解一个问题,在每层递归中应用如下三个步骤: (1)分解(Divide):将原问题分解为一些子问题,子问题的形式与原问题一样,只是规模更小. (2)解决(Conquer):递归地解出子问题.如果子问题规模足够小,则停止递归,直接求解. (3)合并(Combine):将子问题的解组合成原问题的解. 分治思想体现在编码上,