1. 程式人生 > 實用技巧 >演算法(Java實現)—— 分治演算法

演算法(Java實現)—— 分治演算法

分治演算法

分治演算法的設計模式

基本思想

把複雜問題分解成若干互相獨立容易求解的子問題

經典問題

  1. 二分搜尋

  2. 大整數乘法

  3. 棋盤覆蓋

  4. 合併排序

  5. 快速排序

  6. 線性時間選擇

  7. 最接近點對問題

  8. 迴圈賽日程表

  9. 漢諾塔

基本步驟

  1. 分解:將原問題分解成若干規模小的,相互獨立,與原問題形式相同的子問題

  2. 解決:將子問題規模較小而容易被解決則直接解決,否則遞迴的解各個子問題

  3. 合併:將各個子問題的解合併成原問題的解

設計模式

Divide-and-Conquer(P){
if |p| <= n~0
then return(ADHOC(p))
//將 p分解為較小的子問題p1,p2,p3...pk
for i<---1 to k
do yi<---Divide-and-COnquer(pi) //遞迴解決pi
T <---MERGE(y1,y2,...,yk)//合併子問題
return(T)
}

  • |p|表示問題p的規模

  • n0為閾值,表示當問題p的規模不超過n0時,問題已容易直接接觸,不必再繼續分解

  • ADHOC(p)時該分治法中的基本子演算法,用於直接解小規模的問題p

  • 因此,當p的規模不超過n0時直接用演算法ADHOC(p)求解

分治法解決漢諾塔例項

思路分析

  1. 如果只有一個盤,A - >C

  2. 如果盤n > = 2,總是可看作兩個盤1.下面的盤,2.上面的所有盤

  3. 先把最上面的盤A - > B

  4. 把最下邊的盤A - > C

  5. 把B塔的所有盤從B - > C

程式碼實現

package com.why.divide_and_conquer_algorithm;

import java.util.concurrent.CountDownLatch;

/**
* @Description TODO 分治法解決漢諾塔問題
* @Author why
* @Date 2020/11/13 15:34
* Version 1.0
**/
public class HanoiTower {
public static void main(String[] args) {
hanoiTower(5,'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 {
//最上面的盤A->B,移動過程會使用到c
hanoiTower(num - 1,a,c,b);
//最下邊的盤A->C
System.out.println("第"+ num + "個盤從 " + a + "->" + c);
//把B塔的雖有盤從 B -> C 移動過程使用到a塔
hanoiTower(num - 1,b,a,c);
}

}
}