Проблема, с которой вы сталкиваетесь, заключается в том, что у вас есть вызовы функций и циклические конструкции. Трудно распутать их.
Сначала давайте начнем с замены всех операций управления потоком на рекурсию.
// You'll want to start with getPermutionsR(v, n, 0, 0)
void getPermutationsR(int v[], int n, int i, int j)
{
if (i == n)
{
//Display contents of v
}
else if (j == n) {
// By doing nothing, we break out of the loop
}
else
{
// This was your recursive call inside of the loop.
// Note that I'm sending you to to the first loop iteration here.
swap (v, i, j);
getPermutationsR(v, n, i+1, i+1);
swap (v, i, j);
// And the next loop iteration
getPermutationsR(v, n, i, j+1);
}
}
Далее давайте добавим больше состояния, чтобы у нас был только один рекурсивный вызов внутри условия if.
// You'll want to start with getPermutionsR(v, n, 0, 0, 1)
void getPermutationsR(int v[], int n, int i, int j, bool firstCall)
{
if (i == n)
{
//Display contents of v
}
int x = i;
int y = j+1;
if (firstCall) {
swap (v, i, j);
x = i+1;
y = i+1;
}
// My one recursive call. Note that i=n implies j=n.
if (j < n) {
getPermutationsR(v, n, x, y, !firstCall);
}
if (firstCall) {
swap (v, i, j);
}
}
Теперь, когда мы достигли этого, мы имеем его в форме, в которой мы можем преобразовать его в итеративную версию простым способом. Вот трансформация
void recursiveForm (params, recursiveState) {
topHalf...
if (cond) {
recursiveForm(...)
}
bottomHalf...
}
становится
void iterativeForm(params) {
initializeStacks...
pushStacks...
topHalf...
while (stacks not empty) {
if (cond) {
pushStacks...
topHalf...
}
else {
bottomHalf...
popStacks...
}
}
}
Таким образом, применяя этот шаблон, мы получаем что-то вроде:
// You'll want to start with getPermutionsR(v, n, 0, 0, 1)
void getPermutationsI(int v[], int n)
{
stack<int> iStack;
stack<int> jStack;
stack<bool> firstCallStack;
// pushStacks with initial value
iStack.push(0);
jStack.push(0);
firstCallStack.push(1);
// topHalf...
if (iStack.top() == n)
{
//Display contents of v
}
int x = iStack.top();
int y = jStack.top()+1;
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
x = iStack.top()+1;
y = iStack.top()+1;
}
while iStack.size() > 0) {
// if (cond) {
if (jStack.top() < n) {
//pushStacks...
iStack.push(x);
jStack.push(y);
firstCallStack.push(!firstCallStack.top());
// topHalf...
if (iStack.top() == n)
{
//Display contents of v
}
x = iStack.top();
y = jStack.top()+1;
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
x = iStack.top()+1;
y = iStack.top()+1;
}
}
else {
// bottomHalf...
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
}
}
}
}
(Внимание, весь код не проверен и может даже не скомпилироваться. Но идея верна. И это точно такой же алгоритм.)