Рекурсия

May 4, 2010 by admin Комментировать »

Рекурсией (или рекурсивным вызовом) называется вызов функцией самой себя. Рекурсия вполне допустима и даже бывает очень полезной в РНР-скриптах, однако необходимо помнить, что эта операция расходует немало ресурсов.

Рассмотрим пример Пусть на некотором сайте существует раздел "Наши услуги". В этом разделе есть подраздел "Разработка", у которого есть собственный подраздел "Web-сайты". Таким образом, получается иерархическая цепочка, в ко­торой есть и родительские, и дочерние разделы. При этом подраздел "Разработка" одновременно является дочерним для раздела "Наши услуги" и родительским для подраздела "Web-сайты". Каким образом можно определить, есть ли у каждого из разделов подразделы?

Представим структуру сайта в виде массива.

<?php

$navigation = array (

1 => array (

"name" => "Наши услузти",

"parent" => О

),

2 => array (

"name" => "Разработка", "parent" => 1 ),

3 => array (

"name" => "Web-сайты",

"parent" => 2

)

);

?>

В состав массива $navigatior входят три элемента. (Здесь мы умышленно на­чали нумерацию с единицы, чтобы оставить нулевой элемент свободным.) Индекс каждого из элементов (1, 2 или 3) представляет собой их уникальный идентифика­тор. Каждый такой элемент имеет, выражаясь языком баз данных, по два поля: name (название раздела) и parent (номер родительского раздела). Теперь предстоит написать функцию, задачей которой будет выяснить, у каких из перечисленных разделов есть подразделы.

<?php

function has_child($arr,$page_id=0) { foreach ($arr as $index => $field); { if ($field["parent") == $page_id) { if ($page_id != 0) {

echo $arr[$page_id]["neune"] "имеет дочерний элемент <br>"; }

//Внимание рекурсия!

has_child($arr, $index);

}

}

}

//Первый вызов функции

//(остёшьные будут выполнены рекурсивно)

has_child(&navigation);

?>

Напоминание. Если вы решите запустить данный пример на выполнение, не забудьте сначала дописать в него определение массива $navigation из пре­дыдущего примера

Рассмотрим выполнение написанной функции пошагово. В качестве входных данных при первом вызове в функцию поступают массив $navigation (точнее не сам массив, а ссылка на него) и "корневой" элемент (тот самый, с нулевым индек­сом), для которого посредством перебора с помощью конструкции foreach ищутся "потомки". Каждый найденный потомок сам проверяется на наличие "потомков’ именно с помощью рекурсии. Таким образом, в данном примере не приходится вы­зывать функцию has_child() вручную для каждого элемента, так как функция "обходит" все элементы массива самостоятельно. Такой перебор иерархической це-« почки называется рекурсивным спуском.

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

Оставить комментарий

микросхемы мощности Устройство импульсов питания пример приемника провода витков генератора выходе напряжение напряжения нагрузки радоэлектроника работы сигнал сигнала сигналов управления сопротивление усилитель усилителя усиления устройства схема теория транзистора транзисторов частоты