本文内容

  • 分治策略
  • 分治步骤
  • 从合并排序看“分治策略”

分治策略

分治法(divide-and-conquer),“分治法策略”是一种很重要的算法。顾名思义,“分而治之”。将原问题划分成 n 个规模较小,而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。

“分治策略”是很多高效算法的基础,如快速排序、归并排序、傅立叶变换(快速傅立叶变换)。

分治步骤

  • 分解(Divide):将原问题分解成一系列子问题;
  • 解决(Conquer):递归地解各个子问题。若子问题足够小,则直接求解;
  • 合并(Combine):将子问题的结果合并成原问题的解。

备注:

如何划分子问题的规模?从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。换句话说,将一个问题分成大小相等的k个子问题的处理方法是行之有效的。许多问题可以取 k = 2。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。

从合并排序看“分治策略”

合并排序(Merge Sort)算法完全按照上述模式,步骤如下:

  • 分解:将 n 个元素分成各含 n/2 个元素的子序列;
  • 解决:用合并排序发对两个子序列递归地排序;
  • 合并:合并两个已排序的子序列得到排序结果。
元素头文件 MyElement.h
#ifndef MYELEMENT_H_INCLUDED
#define MYELEMENT_H_INCLUDED
 
#define N 10
#define LQ(a,b) ((a)<=(b))
 
typedef int ElementType;
 
void Print(ElementType e[], int n);
 
#endif // MYELEMENT_H_INCLUDED

元素源文件 MyElement.c
#include <stdio.h>
#include "MyElement.h"
 
void Print(ElementType e[], int n)
{
    int i;
    for(i=1; i<n; i++)
        printf("%d ",e[i]);
    printf("\n");
}

合并排序头文件 MergeSort.h
#ifndef MERGESORT_H_INCLUDED
#define MERGESORT_H_INCLUDED
 
#include "MyElement.h"
 
void MergeSort(ElementType e[], int n);
void Main_MergeSort();
 
#endif // MERGESORT_H_INCLUDED

合并排序源文件 MergeSort.c
#include <stdio.h>
#include "MergeSort.h"
#include "MyElement.h"
 
void Merge(ElementType SR[],ElementType TR[],int i,int m,int n)
{
    /* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] */
    int j,k,l;
    for(j=m+1,k=i; i<=m&&j<=n; ++k) /* 将SR中记录由小到大地并入TR */
        if LQ(SR[i],SR[j])
            TR[k]=SR[i++];
        else
            TR[k]=SR[j++];
    if(i<=m)
        for(l=0; l<=m-i; l++)
            TR[k+l]=SR[i+l]; /* 将剩余的SR[i..m]复制到TR */
    if(j<=n)
        for(l=0; l<=n-j; l++)
            TR[k+l]=SR[j+l]; /* 将剩余的SR[j..n]复制到TR */
}
void MSort(ElementType SR[],ElementType TR1[],int s, int t)
{
    /* 将SR[s..t]归并排序为TR1[s..t]。*/
    int m;
    ElementType TR2[N+1];
    if(s==t)
        TR1[s]=SR[s];
    else
    {
        m=(s+t)/2; /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */
        MSort(SR,TR2,s,m); /* 递归地将SR[s..m]归并为有序的TR2[s..m] */
        MSort(SR,TR2,m+1,t); /* 递归地将SR[m+1..t]归并为有序的TR2[m+1..t] */
        Merge(TR2,TR1,s,m,t); /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */
    }
}
/* 归并排序 */
void MergeSort(ElementType e[], int n)
{
    MSort(e,e,1,n-1);
}
 
void Main_MergeSort()
{
    ElementType d[N]= {49,38,65,97,76,13,27,49,55,10};
    printf("排序前:\n");
    Print(d,N);
    MergeSort(d,N);
    printf("排序后:\n");
    Print(d,N);
    printf("\n");
}

再者,若有一个数组,查找其中最大值和最小值,也可以采用分治算法。

#include <stdio.h>
#include <stdlib.h>
 
#define M 10
 
/*  求一个数组中最大值和最小值的分治算法
    参数:
   s 当前分治段的开始下标
   e 当前分治段的结束下标
   meter 表的地址
   max 存储当前搜索到的最大值
   min 存储当前搜索到的最小值
*/
void MaxMin(int s,int e,int meter[],int *max,int *min)
{
    int i;
    if(e-s <= 1)
    {
        if(meter[s] > meter[e])
        {
            if(meter[s] > *max)
                *max = meter[s];
            if(meter[e] < *min)
                *min = meter[e];
        }
        else
        {
            if(meter[e] > *max)
                *max = meter[e];
            if(meter[s] < *min)
                *min = meter[s];
        }
        return ;
    }
    i = s + (e-s)/2;
    MaxMin(s,i,meter,max,min);
    MaxMin(i+1,e,meter,max,min);
}
 
void main()
{
    int meter[M]= {34,67,54,68,23,12,26,97,80,10};
    int max = INT_MIN; /* 用最小值初始化 */
    int min = INT_MAX; /* 用最大值初始化 */
    printf("The array's Max & Min Value as followed:\n");
    MaxMin(0,M - 1,meter,&max,&min); /* 分治法获取最值 */
    printf("\nMax : %d\nMin : %d\n",max,min);
}

下载 Demo

从合并排序算法看“分治法”相关推荐

  1. 算法:分治法之合并排序

    合并排序算法思想: 先将无序序列利用二分法划分为子序列,直至每个子序列只有一个元素(单个元素就是有序),然后再对有序子序列两两进行合并排序. 合并方法是循环地将两个有序子序列当前的首元素进行比较,较小 ...

  2. pythonsort函数时间复杂度_合并排序算法——时间复杂度详解和python代码实现

    递归形式 递归形式是算法中常用到的一种构造思路.递归允许函数或过程对自身进行调用,是对算法中重复过程的高度概括,从本质层面进行刻画,避免算法书写中过多的嵌套循环和分支语法.因此,是对算法结构很大的简化 ...

  3. 趣学算法系列-分治法

    趣学算法系列-分治法 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多实例分析请查看原书内容 第三章 分治 ...

  4. c++两个vector合并_数据结构——算法初步(4)——合并排序算法

    从之前的学习可以看到,对大型vectory要求的排序,选择排序算法显然不符合要求,因为运行时间与输入问题规模大小的平方成比例增加,对于以线性顺序处理向量的元素的大多数排序算法也是如此. 所以要采用不 ...

  5. 合并排序算法排序过程_外部合并排序算法

    合并排序算法排序过程 外部分类 (External sorting) External sorting is a technique in which the data is stored on th ...

  6. 合并排序算法排序过程_基本算法:合并排序

    合并排序算法排序过程 每个程序员都需要了解他们的算法和数据结构. 在研究它们时,您需要确保确切了解它的功能,时间和空间的复杂性以及采用这种方式的原因,并且不仅能够对其进行编码,而且能够手动执行. 这就 ...

  7. 两个有序单链表的合并排序算法

    设计两个有序单链表的合并排序算法 ListList MergeList(LiskList La, LinkList Lb){Lnode *pa = La->next;Lnode *pb = Lb ...

  8. 合并排序算法排序过程_合并排序| 用于大型输入的最佳排序算法之一

    合并排序算法排序过程 What is sorting? 什么是分类? Sorting allows us to process our data in a more organized and eff ...

  9. 排序算法python实现_合并排序算法– Java,C和Python实现

    排序算法python实现 Merge sort is one of the most efficient sorting algorithms. It works on the principle o ...

最新文章

  1. Python 或将成为法国高中的官方编程教学语言
  2. 算法:图(Graph)的遍历、最小生成树和拓扑排序
  3. 几个使用linux内核的系统,[科普] Linux 的内核与 Linux 系统之间的关系
  4. 云栖大会 | 马云提出“新制造”战略将影响全球
  5. android 自定义透明 等待 dialog,Android自定义Dialog内部透明、外部遮罩效果
  6. 乐高机器人亮剑_2500名选手大比拼 全球机器人广州从化“亮剑”
  7. linux切换到字符界面stemctl,CentOS7两种模式
  8. 《三体》动画版官宣!B站出品 刘慈欣“倒吸一口凉气”
  9. JavaSE基础——Java多线程(2)
  10. IDEA自动生成功能
  11. java自制语音识别,JAVA作的语音识别
  12. java 根号x_Java-求根号n
  13. 为什么C语言长盛不衰,永不会过时?
  14. FCC ID认证简介
  15. 视频编码基础:I帧、P帧 和 B 帧
  16. web单页面应用与多页面应用区别
  17. Matrix4x4.TRS()
  18. (fuel)openstack 冷迁移+热迁移
  19. HTML语言中表格的书写中TD TR TH的英文全称
  20. gearman的安装

热门文章

  1. Windows Server 2003防黑小秘决
  2. 《C++游戏编程入门(第4版)》——1.8 Lost Fortune简介
  3. 利用OTP为odoo增强安全访问
  4. 解决Win8.1键盘输入后鼠标左键响应延迟的问题
  5. [c#基础]关于try...catch最常见的笔试题
  6. 泛在电力物联网(能源互联网+物联网)浅析
  7. TLS1.3 协议的Golang 实现——ClientHello
  8. Vue SPA 打包优化实践
  9. JDBC编程的事务处理
  10. 读书笔记--MapReduce 适用场景 及 常见应用