常用十大算法_分治算法

分治算法

 将复杂问题拆分成许多个具有规律的重复性操作的子问题,通过求解子问题再合并,使之成为复杂问题的结果。

分治算法可以求解的一些经典问题:

二分搜索,大整数乘法,棋盘覆盖,合并排序,快速排序

线性时间选择,最接近点对问题,循环赛日程表,汉诺塔

下面以汉诺塔求解为例,了解分治算法:

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

以3盘为例,汉诺塔传统解法流程

常用十大算法_分治算法_第1张图片

 3盘还好,6步完成,但4盘,要15步,5盘,要31步...所以我们可以将 n>=2 的汉诺塔问题,进行拆分。

n==1时:直接将盘从起始位置(A)移动到目标位置(C)

n>=2时:

1,最底层上面所有盘为一个整体,从起始位置(当前为A)移动到暂留位置(当前为B)

2,最底层盘,从起始位置(当前为A)移动到目标位置(当前为C)

3,将上面所有盘的整体,由暂留位置(当前为B)移动到目标位置(当前为C)

执行完上述操作后,递归再次执行上述操作,不过此时的最底层盘变为刚开始的次底层盘,以此类推,直到 n==1 时,结束递归。

常用十大算法_分治算法_第2张图片

 代码实现:

package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.divideAndConquer;

public class 分治算法_DAC_汉诺塔 {
    public static void main(String[] args) {
        hanoiTower(4,'A','B','C');
    }

    /**
     * 分治算法解决汉诺塔问题
     * @param num 汉诺塔盘数
     * @param a 每次递归的起始位置
     * @param b 每次递归的暂留位置
     * @param c 每次递归的目标位置
     */
    public static void hanoiTower(int num,char a,char b,char c){
        if (num==1){
            System.out.println("第1个盘从 "+a+"移动到"+c);
        }else {
            //两个盘及以上的移动策略
            //最底层上面所有盘为一个整体,从起始位置移动到暂留位置
            hanoiTower(num-1,a,c,b);
            //最底层盘,从起始位置移动到目标位置
            System.out.println("第"+num+"个盘从 "+a+"移动到"+"c");
            //将上面所有盘的整体,由暂留位置移动到目标位置
            hanoiTower(num-1,b,a,c);
        }
    }
}
第1个盘从 A移动到B
第2个盘从 A移动到c
第1个盘从 B移动到C
第3个盘从 A移动到c
第1个盘从 C移动到A
第2个盘从 C移动到c
第1个盘从 A移动到B
第4个盘从 A移动到c
第1个盘从 B移动到C
第2个盘从 B移动到c
第1个盘从 C移动到A
第3个盘从 B移动到c
第1个盘从 A移动到B
第2个盘从 A移动到c
第1个盘从 B移动到C

 


其他常用算法,见下各链接

【常用十大算法_二分查找算法】

【常用十大算法_贪心算法】

【常用十大算法_动态规划算法(DP)】

【常用十大算法_KMP算法】

【常用十大算法_普里姆(prim)算法,克鲁斯卡尔(Kruskal)算法】

【常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法】

【常用十大算法_回溯算法】

 

【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)  

 

你可能感兴趣的:(数据结构与算法)