|
|
|
| Есть таблица в БД:
(id_child,id_parent)
(7,5)
(15,8)
(5,2)
(4,3)
(2,1)
|
Мне нужно вывести, например, все id, от которых зависит id_child=7.
В ответе должен полчиться массив (7,5,2,1).
Нужно написать функцию, которая будет рекурсивно вызывать себя.. Помогите разобрать, пожалуйста. | |
|
|
|
|
|
|
|
для: spiner
(28.04.2007 в 00:02)
| | Не понятно, а почему в ответе должна появится пара "2,1"? Вы же сказали, только пары, где id_child=7. | |
|
|
|
|
|
|
|
для: spiner
(28.04.2007 в 00:02)
| | Вот рабочий вариант, не помню только оптимизированый ли. дальше думаю сами разберетесь.
Этот пример строит многомерный массив из линейного, хотя для обхода получившейся рекурентной структуры вам тоже рекурсивка понадобится :-)
#########################################################################
###
### Получение древовидного массива из линейного
###
function GetTree ($table,$p_id='0',$arr_linear=array(),$arr=array())
{
### Первый проход
if(count($arr) == 0)
{
if(count($arr_linear) == 0)
{
$sql = "SELECT NAME,ID,P_ID,SORT FROM `".$table."` WHERE VISIBLE = 'y'";
foreach(mysql_qw($sql) as $x) $arr_linear[$x['ID']] = $x;
}
$arr = GetTree_GetParent($arr_linear,$p_id);
}
foreach($arr as $k => $x)
{
$arr__[$k] = $x;
### Если нащюпали детей
$xx = GetTree_GetParent($arr_linear,$k);
if($xx) $arr__[$k]['CHIL'] = GetTree($table,$k,$arr_linear,$xx);
}
return $arr__;
}
### Дополнение к функции выше
function GetTree_GetParent ($arr,$p_id)
{
foreach ($arr as $k => $x)
{
if(!isset($x['P_ID'])) break;
if($x['P_ID'] == $p_id) $ret[$x['SORT']] = $x;
}
### Сортируем по SORT-у
if(isset($ret))
{
ksort($ret);
foreach ($ret as $x) $ret_[$x['ID']] = $x;
$ret = $ret_;
}
else $ret = false;
return $ret;
}
#########################################################################
|
| |
|
|
|
|
|
|
|
для: forester_
(28.04.2007 в 02:56)
| | Ужас. Вычислительная сложность не ниже O(N^2). Но это полбеды. Беда - что выполняется захват всего дерева, безо всяких ограничений. | |
|
|
|
|
|
|
|
для: Trianon
(28.04.2007 в 10:19)
| | это всего лишь пример показывающий принцип рекурсивного способа, если внимательно вглядется и переписать строк пять, то для обработки можно подавть массив полученный ранее. А этот кусок был написан минут за 20 для получеия карты сайта.
А насчет быстродействия - это как посмотреть, при сложной и ветвистой структуре один sql запрос гораздо бестрее чем куча подзапросов для каждой ветки. | |
|
|
|
|
|
|
|
для: spiner
(28.04.2007 в 00:02)
| | Здесь не нужна (читайте: вредна) рекурсия.
Задача решается итеративным алгоритмом. | |
|
|
|
|
|
|
|
для: Trianon
(28.04.2007 в 10:14)
| | Согласен рекурсия здесь не нужна, почему-то чуть что все сразу начинают использовать рекурсию
вот например итеративное решение, сравнивайте сами
<?php
$host="localhost";
$dbuser="root";
$dbpass="";
$dbname="test";
$arr=array();
$temp=0;
$dbcon=mysql_connect($host,$dbuser,$dbpass);
$dbsel=mysql_select_db($dbname);
$sql="SELECT * FROM test_table WHERE id_child=7";
$query=mysql_query($sql);
$rez=mysql_fetch_assoc($query);
while ($rez['id_parent']!=0){
$temp=$rez['id_parent'];
$arr[7][]=$temp;
$sql="SELECT * FROM test_table WHERE id_child=$temp";
$query=mysql_query($sql);
$rez=mysql_fetch_assoc($query);
}
print_r($arr[7]);
?>
|
| |
|
|
|