20210326-算法学习-程序员常用的10种算法(Algorithm)-分治算法(Divide-and-Conquer)

一.分治算法

  1.分治算法介绍:分治法是一种很重要的算法,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并

  2.分治算法求解的经典问题:二分搜索 大整数乘法 棋盘覆盖 合并排序 快速排序 线性时间选择 最接近点对问题 循环赛日程表 汉诺塔

  3.分治算法的基本步骤:

    1)分治法在每一层递归上都有三个步骤:

      *分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题

      *解决:若子问题规模较小而容易被解决则直接解决,否则递归的解决各个子问题

      *合并:将各个子问题的解 合并为原有问题

二.分治算法设计模式

  1.分治(Divide-and-Conquer(P))算法设计模式如下:

if |P| <=n0 then return(ADHOC(P))
//将P分解为较小的子问题 P1,P2,……,Pk
for i<-1 to k
do yi <- Divied-and-Conquer(Pi) 递归解决Pi
T <- MERGE(y1,y2,……,yk)合并子问题 return(T)

其中 |P| 表示问题P的规模,n0为(阈值),表示当问题P的规模不超过 n0时,问题已容易直接溢出,
不必在继续分解,ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P,因此,
当P的规模不超过 n0时直接用算法 ADHOC(P)求解,算法 MERGE(y1,y2,……,yk)是该分治算法中的合并子算法,
用于将P的子问题 P1,P2,……,Pk的相应的解 y1,y2,……,yk合并为P的解

三.分治算法经典案例1(汉诺塔游戏)

  1.汉诺塔游戏演示和思路分析

  

*如果是有一个盘, A->C
*如果我们有 n >= 2 情况,我们总是可以看做是两个盘 1.最下边的盘 2. 上面的盘

*先把最上面的盘 A->B
*把最下边的盘 A->C
*把B塔的所有盘 从 B->C

2.代码实例

package com.atProjectCombat;
/**
 * @Author: lisongtao
 * @Date: 2021/4/20 10:37
 */


/**
 * @ClassName Hanoitower
 * @Description : 汉诺塔游戏
 * @Author DELL
 * @Date 2021/04/20 10:37
 **/
public class Hanoitower {
    public static void main(String[] args) {
        hanio(3, 'A', 'B', 'C');
    }

    //使用分治算法完成汉诺塔移动
    public static void hanio(int num, char a, char b, char c) {
        //如果只有一个盘
        if (num == 1) {
            System.out.println("第1个盘从" + a + "移动到" + c);
        } else {
            //如果我们有 n >= 2 的情况,我们总是可以看做是两个盘,
            // 1.最下面的一个盘,2.上面的所有盘
            //先把最上面的所有盘 A->B,移动过程中或使用C
            hanio(num - 1, a, c, b);
            System.out.println("第" + num + "个盘从" + a + "移动到" + c);
            //把B塔的所有盘 从 B-C,移动过程使用到 A塔
            hanio(num - 1, b, a, c);
        }

    }
}

  

 

posted @ 2021-03-27 17:37  firefox7557  阅读(241)  评论(0)    收藏  举报