分治算法指的是将我们需要解决的问题分而解之,将大的问题分解成小的问题,算法最后的结果就是最后的那个小问题的解,分治算法中的小问题之间往往是可以独立的,不是相互依赖的。常见的诸多高效算法中都运用了分治算法的基础思想——二分搜索、大整数除法、合并排序、快速排序、傅里叶变换。在这里我们展示的是一个分治排序算法的经典运用——汉诺塔。
汉诺塔本来要求的是要我们将n个盘子按照相应的固定移动到我们的目标位置,当有两个盘子的时候是很简单的我们知道只需要将上边小的盘子移动到我们的协助位置,再讲靠近下面的大盘子 移动到我们的目标位置,最后在将位于协助位置上较小的盘子移动到我们的目标位置。但是当我们的n是很大的时候,我们应该如何处理呢,这时候我们可以采取的就是讲我们的问题简单化,将上边所有的盘子都看成是一个整体,然后问题就回归到了我们最基础的问题上了,也就是将我们的问题分治了,这个分治的过程体现在我们递归调用的过程中。当我们用n个盘子的时候上面的n-1个盘子可能仍然是多于两个的这时候我们就需要继续进行分治,这个过程体现在递归的调用中。
递归调用的尽头就是我们分治的最小的问题,我们将更大的问题连续分解成更小的问题,直到这个小问题是我们可以直接解决的为止。在这个算法回溯的过程中就是我们盘子移动的过程,简而言之:递归调用的过程是在进行问题分解,问题的解决是发生在回溯的路上。
算法代码的实现:
public class Hannoita {
static int count=0;
public static void main(String[] args) {
hanNouTa(5);
System.out.println("operaed all "+count);
}
public static void hanNouTa(int num){
hanNouTa(num,"startCol","tarCol","helperCol");
}
public static void hanNouTa(int num,String startColumn,String targetColumn,String helperColumn){
if (num==1){
System.out.println("Move ( "+num+" ) from " + startColumn +" to "+targetColumn);
count++;
return;
}
else{
hanNouTa(num-1,startColumn,helperColumn,targetColumn);
System.out.println("Move ( "+num+" ) from " + startColumn +" to "+targetColumn);
count++;
hanNouTa(num-1,helperColumn,targetColumn,startColumn);
}
}
}