Рекурсивні виклики та петлі - це лише два способи / конструкції для здійснення ітеративного обчислення.
А while
петля відповідає хвостовій рекурсії виклику (дивіться , наприклад , тут ), тобто ітерація , в якій вам не потрібно зберігати проміжні результати між двома ітераціями (всі результати одного циклу готові , коли ви входите в наступний цикл). Якщо вам потрібно зберегти проміжні результати, які ви зможете знову використовувати пізніше, ви можете використовувати while
цикл разом зі стеком (див. Тут ), або не хвостовий рекурсивний (тобто довільний) рекурсивний виклик.
Багато мов дозволяють використовувати обидва механізми, і ви можете вибрати той, який вам більше підходить, і навіть змішати їх разом у вашому коді. В таких необхідних мовах, як C, C ++, Java тощо, ви зазвичай використовуєте a while
або for
цикл, коли вам не потрібен стек, а ви використовуєте рекурсивні дзвінки, коли вам потрібен стек (ви неявно використовуєте стек виконання). Haskell (функціональна мова) не пропонує структуру управління ітерацією, тому для виконання ітерації ви можете використовувати лише рекурсивні дзвінки.
У вашому прикладі (див. Мої коментарі):
// queens should have type int [] , not int.
private boolean placeQueen(int row, int [] queens, int n)
{
boolean result = false;
if (row < n)
{
// Iterate with queens[row] = 1 to n - 1.
// After each iteration, you either have a result
// in queens, or you have to try the next column for
// the current row: no intermediate result.
while ((queens[row] < n - 1) && !result)
{
queens[row]++;
if (verify(row,queens,n))
{
// I think you have 'result' here, not 'ok'.
// This is another loop (iterate on row).
// The loop is implemented as a recursive call
// and the previous values of row are stored on
// the stack so that we can resume with the previous
// value if the current attempt finds no solution.
result = placeQueen(row + 1,queens,n);
}
}
if (!result) {
queens[row] = -1;
}
}else{
result = true;
}
return result;
}