объяснение рекурсивного массива c

#c #recursion

#c #рекурсия

Вопрос:

Здравствуйте, я изучаю рекурсию, и в настоящее время мне нужно решить пару сложных задач — вот одна из рекурсивных функций

 int rec(int niz[], int start, int end){

if (start == end)
{

    return niz[start]; // vraca zadnji
}

int temp = rec(niz, start 1, end);


// control output
cout << "n-----n";
cout << "start "  << start << endl;
cout << "niz[start] "  << niz[start] << endl;
cout << "end "  << end << endl;
cout << "temp "  << temp << endl;
cout << "n-----------------------------------------n";
//contrl output end

return ((niz[start] < temp) ? niz[start] : temp);
}
  

я включил блок cout для управления тем, что используется в вызовах. вот основная часть

     int niz[] = {1,2,3,4,5,6,7}; 
    cout << rec(niz, 0, 3);
  

и вот мой вывод:

 -----
start 2
niz[start] 3
end 3
temp 4
------------------

----- 
start 1
niz[start] 2
end 3
temp 3
------------------

-----
start 0
niz[start] 1
end 3
temp 2
------------------

1
  

кто-нибудь может объяснить мне, как вычисляется и возвращается значение temp и как я получаю 1 в качестве возврата этой функции?

Заранее благодарю вас!

Ответ №1:

Рекурсивная функция — это функция, которая вызывает саму себя.

 int temp = rec(niz, start 1, end);
  

Здесь вы вызываете функцию «rec» внутри one, но с измененным параметром (start 1). Вы вызываете эти функции внутри друг друга до тех пор, пока «начало» не будет равно «концу» (затем оно возвращается)

 if (start == end)
{

    return niz[start]; // vraca zadnji
}
  

После возврата самого глубокого массива второй самый глубокий массив продолжает свой поток, печатая некоторую информацию.

 cout << "n-----n";
cout << "start "  << start << endl;
cout << "niz[start] "  << niz[start] << endl;
cout << "end "  << end << endl;
cout << "temp "  << temp << endl;
cout << "n-----------------------------------------n";
  

Затем он возвращает наименьшее значение между niz [start] и temp (локальные значения).

 return ((niz[start] < temp) ? niz[start] : temp);
  

Затем третий по глубине массив продолжает свой поток и так далее. Пока не дойдет до первой функции.

В вашей основной части вы устанавливаете end равным 3, поэтому он выполняет операцию над первыми 3 элементами (он переходит к четвертому элементу, но ничего не делает, кроме возврата его значения). Вы получаете 1, сравнивая значение niz[0], которое вы передали как start, и temp, возвращаемое рекурсивной функцией (которая оказывается одинаковой). Оно равно, поэтому возвращаемое значение равно niz[0], то есть 1;

При использовании рекурсивных функций у вас должна быть какая-то «точка выхода», которая предотвращает бесконечность рекурсии, т. е.

 if (start == end)
{   
    return niz[start];
}
  

В общем случае рекурсивные функции выглядят следующим образом:

 f()
{
    //return condition
    //some work
    f();
    //some work
    //return
}
  

И вы можете посмотреть на них следующим образом

 f()
{
    //some code
    f()
    {
        //some code
        f()
        {
            //some code
            f()
            {
                ...
                //eventually the return condition is met
            }
            //some code
            //return
        }
        //some code
        //return
    }
    //some code
    //return
}
  

Имейте в виду, что необработанная рекурсия может привести к возможной утечке памяти, поскольку каждый вызов функции сопровождается дополнительными данными.

 f()
{
    f();
}
  

Это приведет к переполнению стека из-за созданных системных данных;

Возможно, вы захотите посмотреть «Начало», чтобы лучше понять его 🙂

Ответ №2:

  rec(niz, 0, 3)                          (D)
  |
  ---->rec(niz, 1, 3)                    (C)
        |
        ----> rec(niz, 2, 3)             (B)
               |
               ----> rec(niz, 3, 3)      (A)
  

Вы вызываете (D), который вызывает (C) для вычисления temp и так далее вплоть до (A). В (A) start==end и это возвращает niz[3] = 4 .

В (B):

temp = 4 (результат выполнения (A))

start = 2

As 4 больше, чем niz[start] = 3 (B) возвращает 3

В (C):

temp = 3 (результат выполнения (B))

start = 1

As 3 больше, чем niz[start] = 2 (B) возвращает 2

В (D):

temp = 2 (результат (C))

start = 0

As 2 больше, чем niz[start] = 1 (B) возвращает 1

Ответ №3:

Ваша рекурсивная строка находится перед блоком инструкции print. По природе рекурсии она вызывает функцию в этой рекурсивной строке и останавливает выполнение вызывающей функции до тех пор, пока вызываемый объект не завершит работу. Поэтому вы вызываете следующий элемент, который должен быть обработан, прежде чем печатать текущий элемент.

В вашем примере происходит следующее:

 Layer 1:
    Is start equal to end? No.
    What is the result of the next element? Don't know yet, recurse.
Layer 2:
    Is start equal to end? No.
    What is the result of the next element? Don't know yet, recurse.
Layer 3:
    Is start equal to end? No.
    What is the result of the next element? Don't know yet, recurse.
Layer 4:
    Is start equal to end? Yes!
    Return the current element, 4.
    End layer 4.
Layer 3:
    Now know next element, start printing for the 3rd element.
    Return 3.
    End layer 3.
Layer 2:
    Now know the next element, start printing for the 2nd element.
    Return 2.
    End layer 2.
Layer 1:
    Now know the next element, start printing for the 1st element.
    Return 1.
    End layer 1.
End program.
  

Как вы можете видеть, элементы массива печатаются в обратном порядке, потому что инструкции print выполняются после рекурсивного вызова. Я бы хотел, чтобы они печатались по порядку, распечатайте их перед рекурсивным вызовом или создайте буфер и добавьте каждый раздел печати в начало буфера.