Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Рекурсивная функция
 
 автор: spiner   (28.04.2007 в 00:02)   письмо автору
 
 

Есть таблица в БД:

(id_child,id_parent)
(7,5)
(15,8)
(5,2)
(4,3)
(2,1)

Мне нужно вывести, например, все id, от которых зависит id_child=7.
В ответе должен полчиться массив (7,5,2,1).
Нужно написать функцию, которая будет рекурсивно вызывать себя.. Помогите разобрать, пожалуйста.

   
 
 автор: Unkind   (28.04.2007 в 00:11)   письмо автору
 
   для: spiner   (28.04.2007 в 00:02)
 

Не понятно, а почему в ответе должна появится пара "2,1"? Вы же сказали, только пары, где id_child=7.

   
 
 автор: forester_   (28.04.2007 в 02:56)   письмо автору
 
   для: 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;
   }

   #########################################################################

   
 
 автор: Trianon   (28.04.2007 в 10:19)   письмо автору
 
   для: forester_   (28.04.2007 в 02:56)
 

Ужас. Вычислительная сложность не ниже O(N^2). Но это полбеды. Беда - что выполняется захват всего дерева, безо всяких ограничений.

   
 
 автор: forester_   (28.04.2007 в 14:27)   письмо автору
 
   для: Trianon   (28.04.2007 в 10:19)
 

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

А насчет быстродействия - это как посмотреть, при сложной и ветвистой структуре один sql запрос гораздо бестрее чем куча подзапросов для каждой ветки.

   
 
 автор: Trianon   (28.04.2007 в 10:14)   письмо автору
 
   для: spiner   (28.04.2007 в 00:02)
 

Здесь не нужна (читайте: вредна) рекурсия.
Задача решается итеративным алгоритмом.

   
 
 автор: вит   (28.04.2007 в 10:57)   письмо автору
 
   для: 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]);
?>

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования