汉诺塔问题的递归与迭代实现
递归实现
/**
* 递归算法
* @param src 源组柱子
* @param tar 目标柱子
* @param temp 中介柱子
* @param amount 盘子的数量
*/
public void recurHannoi(String src, String tar, String temp, int amount) {
if (amount == 1) {
System.out.println(src + "-->" + tar);
} else {
recurHannoi(src, temp, tar, amount - 1);
recurHannoi(src, tar, temp, 1);
recurHannoi(temp, tar, src, amount - 1);
}
}
迭代算法
/**
* 迭代算法
*/
public void iterateHannoi(String start, String end, String temp, int amount) {
// 汉诺塔
Hannoi hannoi = new Hannoi(amount, start, end, temp);
// 栈
Stack stack = new Stack();
stack.push(hannoi);
while (stack.top != -1) {
Hannoi h1 = stack.pop();
int amount1 = h1.amount;
String start1 = h1.start;
String end1 = h1.end;
String temp1 = h1.temp;
// 源柱子只有一个盘子直接移动
if (amount1 == 1) {
System.out.println(start1 + "-->" + end1);
} else {
/*
* 正常是H(n -1,A - > B) H(1,A -> C) H(n-1,B—>C)
* 但由于栈先进后出的特性这里选择反正来
* 当然也可以使用队列
*/
// n - 1 个盘子从B -> C
stack.push(new Hannoi(amount1 - 1, temp1, end1, start1));
// 剩下一个就直接移动
stack.push(new Hannoi(1, start1, end1, temp1));
// n -1 个盘子从A -> B
stack.push(new Hannoi(amount1 - 1, start1, temp1, end1));
}
}
}
// 自定义栈
static class Stack {
// 栈的最大空间
private final static int MaxSize = 100;
Hannoi[] data = new Hannoi[MaxSize];
int top = -1;
// 入栈
public void push(Hannoi hannoi) {
// 栈满了
if (top == MaxSize - 1) {
System.err.println("栈满了");
}
data[++top] = hannoi;
}
// 出栈
public Hannoi pop() {
if (top == -1) {
System.err.println("栈空了");
}
return data[top--];
}
}
// 保存汉诺塔状态
static class Hannoi {
// 盘子的数量
int amount;
// 源柱
String start;
// 中介子
String temp;
// 目标柱
String end;
public Hannoi(int amount, String start, String end, String temp) {
this.amount = amount;
this.start = start;
this.end = end;
this.temp = temp;
}
public Hannoi() {
}
}
效率测试
@Test
public void testRecursion() {
long start_time = System.currentTimeMillis();
recurHannoi("A", "C", "B", 20);
long end_start = System.currentTimeMillis();
System.out.println("递归算法花费的时间是:" + (end_start - start_time));
}
@Test
public void testIteration() {
long start_time1 = System.currentTimeMillis();
iterateHannoi("A", "C", "B", 2);
long end_time1 = System.currentTimeMillis();
System.out.println("迭代算法花费的时间是:" + (end_time1 - start_time1));
}
递归算法很简单,迭代算法则是稍微复杂(无非是自己模拟了栈)
PS:有个疑问
这里的迭代和递归算法经过测试,差距基本没有(个人感觉值Hannoi这个类的对象new了太多次)
希望懂的大佬可以指定下如何改进迭代算法