判断数组 a 是不是一个等差数列
使用栈模拟递归解法
struct Param : public Object
{
Param(int begin = -1, int end = -1, int d = -1)
{
this->begin = begin;
this->end = end;
this->d = d;
this->ret = false;
}
int begin;
int end;
int d;
bool ret;
};
bool IsArithProg(int a[], int begin, int end, int& d)
{
LinkStack<Param> st;
Param obj(begin, end);
Param ans; // ans 为模拟递归后得到的结果
st.push(obj);
while(st.size() > 0)
{
Param curr = st.top();
if(curr.begin == curr.end) // 递归出口,数列只有一个元素时
{
ans.begin = curr.begin;
ans.end = curr.end;
ans.ret = true;
st.pop();
}
else if((curr.end - curr.begin) == 1) // 递归出口,数列只有两个元素时
{
ans.begin = curr.begin;
ans.end = curr.end;
ans.d = a[curr.end] - a[curr.begin];
ans.ret = true;
st.pop();
}
else
{
if((curr.begin == (ans.begin - 1)) && (curr.end == ans.end)) // 子问题解决,带着子问题的答案解决当前问题
{
if(ans.ret && ((a[curr.begin + 1] - a[curr.begin]) == ans.d)) // 子数组为等差数列并且子数组的第一个元素减去当前元素的值等于子数组的公差
{
ans.begin = curr.begin;
st.pop();
}
else // 不满足等差数列,直接退出循环
{
ans.ret = false;
break;
}
}
else
{
st.push(Param(curr.begin + 1, curr.end)); // 问题分解,将子问题入栈
}
}
}
return (ans.ret ? (d = ans.d, true) : false);
}
bool IsArithProg(int a[], int len, int& d)
{
return IsArithProg(a, 0, len - 1, d);
}
将原问题分解成两个子问题
struct Param : public Object
{
Param(int begin = -1, int end = -1, int d = -1)
{
this->begin = begin;
this->end = end;
this->d = d;
this->ret = false;
}
int begin;
int end;
int d;
bool ret;
};
bool IsArithProg(int a[], int begin, int end, int& d)
{
LinkStack<Param> st;
LinkStack<Param> answer;
Param obj(begin, end); // 目标问题
st.push(obj);
while(st.size() > 0)
{
Param ans;
Param curr = st.top(); // 当前问题
if(curr.begin == curr.end) // 递归出口,数列只有一个元素时
{
ans.begin = curr.begin;
ans.end = curr.end;
ans.ret = true;
st.pop(); // 当前问题解决
answer.push(ans); // 答案入栈
}
else if((curr.end - curr.begin) == 1) // 递归出口,数列只有两个元素时
{
ans.begin = curr.begin;
ans.end = curr.end;
ans.d = a[curr.end] - a[curr.begin];
ans.ret = true;
st.pop(); // 当前问题解决
answer.push(ans); // 答案入栈
}
else
{
Param ans0;
Param ans1;
if(answer.size() > 0) // 栈顶找答案
{
ans0 = answer.top();
answer.pop();
}
if(answer.size() > 0) // 栈顶找答案
{
ans1 = answer.top();
answer.pop();
}
if((curr.begin == ans0.begin) && (curr.end == ans1.end)) // 找到的答案能否解决当前问题
{
/* [ans0.begin, ans1.end] 组成的数列构成等差数列, 则将新的答案入栈 */
if(ans0.ret && ans1.ret && (ans0.d == ans1.d))
{
ans.begin = curr.begin;
ans.end = curr.end;
ans.d = ans0.d;
ans.ret = ans0.ret;
st.pop();
answer.push(ans);
}
else
{
ans.ret = false;
answer.push(ans);
break;
}
}
else // 将当前问题分解成子问题
{
int mid = (curr.begin + curr.end) / 2;
Param np0(curr.begin, mid);
Param np1(mid, curr.end);
/* 找到的答案不能解决当前问题,将答案重新入栈 */
if(ans1.begin != -1)
{
answer.push(ans1);
}
/* 找到的答案不能解决当前问题,将答案重新入栈 */
if(ans0.begin != -1)
{
answer.push(ans0);
}
/* 将子问题入栈 */
st.push(np0);
st.push(np1);
}
}
}
return (answer.top().ret ? (d = answer.top().d, true) : false);
}
bool IsArithProg(int a[], int len, int& d)
{
return IsArithProg(a, 0, len - 1, d);
}
汉诺塔问题

递归解法
void hanoi_rec(int n, char a, char b, char c)
{
if(n > 0)
{
hanoi_rec(n - 1, a, c, b); // 将 n-1 个木块借助C柱由A柱移动到B柱
cout << a << " -> " << c << endl; // 将最底层的唯一木块直接移动到C柱
hanoi_rec(n - 1, b, a, c); // 将 n-1 个木块借助A柱由B柱移动到C柱
}
}
非递归解法
struct Param : public Object
{
Param(int n = -1, int a = 0, int b = 0, int c = 0)
{
this->n = n;
this->a = a;
this->b = b;
this->c = c;
}
int n;
char a;
char b;
char c;
};
void hanoi_non(int n, char a, char b, char c)
{
if(n > 0)
{
LinkStack<Param> st;
LinkStack<Param> answer;
Param obj(n, a, b, c); // 目标问题
st.push(obj);
while(st.size() > 0)
{
Param curr = st.top(); // 当前问题
if(curr.n == 0)
{
cout << curr.a << " -> " << curr.c << endl;
st.pop();
}
else if(curr.n == 1) // 出口
{
cout << curr.a << " -> " << curr.c << endl; // 直接将A柱最底层唯一的木块移动到C柱
st.pop(); // 最小问题解决
answer.push(curr); // 将答案入栈
}
else
{
Param ans0;
Param ans1;
/* 尝试取答案 */
if(answer.size() > 0)
{
ans1 = answer.top();
answer.pop();
}
/* 尝试取答案 */
if(answer.size() > 0)
{
ans0 = answer.top();
answer.pop();
}
if((curr.n == (ans0.n + 1)) && (curr.a == ans0.a) && (curr.b == ans0.c) && (curr.c == ans0.b) &&
(curr.n == (ans1.n + 1)) &&(curr.a == ans1.b) && (curr.b == ans1.a) && (curr.c == ans1.c)) // 答案与当前的问题相匹配,尝试解决当前问题
{
st.pop(); // 当前问题解决
answer.push(curr); // 将答案入栈
}
else // 需要继续分解问题
{
/* 答案不能解决当前问题,重新将答案入栈 */
if(ans0.n != -1)
{
answer.push(ans0);
}
/* 答案不能解决当前问题,重新将答案入栈 */
if(ans1.n != -1)
{
answer.push(ans1);
}
/* 问题分解 */
st.push(Param(curr.n - 1, curr.b, curr.a, curr.c));
st.push(Param(0, curr.a, curr.b, curr.c));
st.push(Param(curr.n - 1, curr.a, curr.c, curr.b));
}
}
}
}
}
使用栈模拟递归解决等差数列与汉诺塔问题
这篇博客探讨了如何使用栈来模拟递归算法,分别解决了判断一个数组是否为等差数列以及汉诺塔问题。对于等差数列,通过将问题分解为子问题并利用栈存储中间结果来实现;对于汉诺塔问题,同样利用栈来保存中间状态,避免了递归调用。这种方法有助于理解递归过程,并能提高算法效率。
481

被折叠的 条评论
为什么被折叠?



