помогите с рекурсией

Тема в разделе "PHP", создана пользователем able, 19 май 2008.

Статус темы:
Закрыта.
Модераторы: latteo
  1. able

    able

    Регистр.:
    5 апр 2008
    Сообщения:
    226
    Симпатии:
    66
    а то голова болит под вечер..
    есть структура базы id | name | parentid
    т.е. вложенность может быть бесконечная. накидал ф-цию

    PHP:
            function showtree($id) {
                global 
    $db$content;

                
    $result $db->query("SELECT * FROM ".MPREF."news_categories WHERE pcategory = ".$id.";");
                    while (
    $line $db->get_row($result)) {
                    
    $content .= $line['name']."<br />";
                        
    showtree($line['id']);
                    }
                

            }

    прекрасно выводит друг за дружкой все категории.
    а как отслеживать уровень вложенность каждой категории?
    т.е. чтобы на выходе было примерно так
    -0
    --0.0
    --0.1
    ---0.1.0
    ---0.1.1
    -1
    --1.0
    ---1.0.0

    ну и тд..
     
  2. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    переменная static
    http://ru2.php.net/manual/ru/language.variables.scope.php
    тоесть чтото вроде:
    PHP:
    function showtree($id) {
                global 
    $db$content;
                static 
    $level=0;
                
    $level++;
                
    $result $db->query("SELECT * FROM ".MPREF."news_categories WHERE pcategory = ".$id.";");
                    while (
    $line $db->get_row($result)) {
                    
    $content .= $line['name']."<br />";
                        
    showtree($line['id']);
                    }
                
    $level--;
            }  
     
  3. masto

    masto Прохожие

    чтоб вывести все категории рекурсии вообще не надо :) (это к приведённому примеру)

    по сабжу:
    PHP:
    <?php

    if(!($db_link mysql_connect('localhost''user''password')))
        echo 
    'Could not connect to database!' mysql_errno() . ' : ' mysql_error();

    if(!(
    mysql_select_db('database'$db_link)))
        echo 
    'Could not open database!' mysql_errno() . ' : ' mysql_error();

    function 
    get_heirachy($par_id$db_link)
    {
        
    $qry 'SELECT `id` FROM `categories` WHERE `parent_id` = ' $par_id;
        
    $res mysql_query($qry$db_link);
        while(
    $parent mysql_fetch_row($res))
        {
            echo 
    '<ul>';
            
    get_next($parent$db_link);
            echo 
    '</ul>';
        }
        return 
    true;
    }

    function 
    get_next($parent$db_link)
    {
        foreach(
    $parent as $k => $v)
        {
            
    $qry 'SELECT `id` FROM `categories` WHERE `id` = ' $v;
            
    $res mysql_query($qry$db_link);
            
    $echo mysql_fetch_row($res);
            echo 
    $echo[0] . '<br />';
            
    get_heirachy($v$db_link);
            return 
    true;
        }
    }

    get_heirachy(0$db_link);

    ?>
    PS также рекоммендую почитать http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
     
  4. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    без рекурсии конечно можно, но очень сложно, и если память позволяет то проще сделать рекурсию... если хочешь оптимизировать чтобы не было рекурсии просто делаешь стек используемых переменных. здесь это id и у меня еще level, делаем массив из них и еще переменную указатель текущей записи в нашем "стеке", и обходим массив по аналогии с нашим рекурсивным алгоритмом. Вот только ТС не спрашивал как избавиться от рекурсии :)

    теперь по твоему коду:
    1 - может я невнимательно читал конечно но на вопрос ТС "как отслеживать уровень вложенность каждой категории?" он не отвечает.
    2 - он является таким же рекурсивным как и алгоритм ТС.
    3 - как по мне так он сложнее - зачем двойная вложенность функций? для запутывания кода?
     
  5. masto

    masto Прохожие

    вопрос:
    ответ: мой код именно это и делает

    на уникальность и/или гениальность кода не претендую, но с поставленной задачей он справляется, хотя можно его и доработать. сам уже давно для подобных целей юзаю sql и/или SPL.

    Замечание о рекурсии относилось к 1-му посту
     
  6. mentanos

    mentanos Постоялец

    Регистр.:
    27 дек 2007
    Сообщения:
    128
    Симпатии:
    35
    вложенность отслеживается элементарно и без статики.

    function showtree($id,$x) {
    ...
    showtree(...,$x+1);
    }

    и первый вызов showtree(...,0);

    если по вложенности определяется отступ, тогда первый вызов showtree(...,''), а внутренние вызовы showtree(...,$x.'-')
     
  7. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    а зачем? чем тебе статика не нравится? рекурсия понятно - ресурсоемко и неустойчиво при высоком уровне вложенности, но статика это же вообще даже не функция самое что ни на есть ядро php... так можно и без php обойтись, а зачем? :)
     
  8. denm

    denm Читатель

    Заблокирован
    Регистр.:
    31 июл 2007
    Сообщения:
    26
    Симпатии:
    2
    А что более ресурсоёмко ? Куча запросов к базе или рекурсия ?
     
  9. masto

    masto Прохожие

    А при рекурсии ты не делаешь запросов?
     
  10. ziavra

    ziavra Постоялец

    Регистр.:
    14 сен 2006
    Сообщения:
    123
    Симпатии:
    55
    +1 за mentanosa. Imho, его код более читабелен и на другие языки, в случае чего, портируется просто. И причем тут противопоставление рекурсии и статики? В твоем примере рекурсия никуда не девается же тоже.

    P.S. Ну и шутка в тему: чтобы понять рекурсию, надо сначала понять рекурсию. ;)
     
Статус темы:
Закрыта.