Wywołania i pętle rekurencyjne to tylko dwa sposoby / konstrukcje do implementacji obliczeń iteracyjnych.
A while
odpowiada pętli do wywołania tail-rekurencyjne (patrz przykład tutaj ), czyli iteracji, w których nie trzeba się zapisywać wyniki pośrednie między dwoma iteracji (wszystkie wyniki jednego cyklu są gotowe kiedy wchodzi się do następnego cyklu). Jeśli chcesz zapisać wyniki pośrednie, których możesz użyć ponownie później, możesz albo użyć while
pętli razem ze stosem (patrz tutaj ), albo rekurencyjne (tzn. Arbitralne) wywołanie rekurencyjne.
Wiele języków pozwala korzystać z obu mechanizmów i możesz wybrać ten, który bardziej Ci odpowiada, a nawet mieszać je razem w kodzie. W imperatywnych językach, takich jak C, C ++, Java itp. Zwykle używasz pętli while
lub for
, gdy nie potrzebujesz stosu, i używasz wywołań rekurencyjnych, gdy potrzebujesz stosu (domyślnie używasz stosu wykonawczego). Haskell (język funkcjonalny) nie oferuje struktury kontroli iteracji, więc do wykonywania iteracji można używać wyłącznie wywołań rekurencyjnych.
W twoim przykładzie (patrz moje komentarze):
// 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;
}