Списки смежности и рекурсия.

Alexi

Новичок
Списки смежности и рекурсия.

Здравствуйте.
Работаю с деревом иерархии. Использую списки смежности. Вот имеющийся массив:
PHP:
Array
(
    [0] => Array
        (
            [news_id] => 2
            [parent_id] => 0
            [title] => Новости сайта
            [sorting] => 1
            [a_tree] => Array
                (
                    [0] => Array
                        (
                            [news_id] => 7
                            [parent_id] => 2
                            [title] => Новости сайта 3
                            [sorting] => 1
                            [a_tree] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [news_id] => 6
                            [parent_id] => 2
                            [title] => Новости сайта 2
                            [sorting] => 2
                            [a_tree] => Array
                                (
                                    [0] => Array
                                        (
                                            [news_id] => 8
                                            [parent_id] => 6
                                            [title] => Новости сайта 121
                                            [sorting] => 8
                                            [a_tree] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [news_id] => 9
                                                            [parent_id] => 8
                                                            [title] => Новости сайта 1211
                                                            [sorting] => 91
                                                            [a_tree] => Array
                                                                (
                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                    [2] => Array
                        (
                            [news_id] => 5
                            [parent_id] => 2
                            [title] => Новости сайта 1
                            [sorting] => 3
                            [a_tree] => Array
                                (
                                )

                        )

                )

        )

    [1] => Array
        (
            [news_id] => 1
            [parent_id] => 0
            [title] => Главные новости
            [sorting] => 2
            [a_tree] => Array
                (
                )

        )

    [2] => Array
        (
            [news_id] => 3
            [parent_id] => 0
            [title] => Музыкальные новости
            [sorting] => 3
            [a_tree] => Array
                (
                    [0] => Array
                        (
                            [news_id] => 10
                            [parent_id] => 3
                            [title] => Муз. новость 1
                            [sorting] => 10
                            [a_tree] => Array
                                (
                                )

                        )

                )

        )

    [3] => Array
        (
            [news_id] => 4
            [parent_id] => 0
            [title] => Ещё новости
            [sorting] => 4
            [a_tree] => Array
                (
                    [0] => Array
                        (
                            [news_id] => 11
                            [parent_id] => 4
                            [title] => Ещё новость 1
                            [sorting] => 11
                            [a_tree] => Array
                                (
                                )

                        )

                )

        )

)
Вопрос: нужно зная текущий news_id, построить массив с его родителями.
Например news_id равен 9, тогда массив его родителей будет выглядеть {8, 6, 2}

Использую для этого рекурсивную функцию, но когда происходить условие, при котором надо выйти из неё, выход происходит из одного уровня, а дальше всё равно происходит наполнение массива, в результате кривой результат.
 

AmdY

Пью пиво
Команда форума
используй какой-нибудь флаг, указывающий, что пора завершить, допустим статическую переменную или возвращаемое значение.
ты бы лучше привёл кусок кода вставляй сюда http://phpclub.ru/paste/
 

Фанат

oncle terrible
Команда форума
для получения родителей рекурсия нафиг не нужна.
сделай цикл, выход из которого - нулевой родитель
 

fixxxer

К.О.
Партнер клуба
Вообще, любой рекурсивный алгоритм можно реализовать без рекурсии, это теоретически было доказано лет 50 назад =)
 

Фанат

oncle terrible
Команда форума
Это рекурсивный. А здесь никакого рекурсивного алгоритма нет
 

rotoZOOM

ACM maniac
Алгоритм поиска в таком массиве элемента с заданным news_id легче всего выполнить рекурсией, а уж если уже нашел такой элемент, то и составить список родителей проще простого.
PHP:
function getParentList ($arr,$newsid)
{
       foreach ($arr as $val){
              if ($val['news_id']==$newsid)return array();
              $ret=getParentList($val['a_tree']);
              if ($ret!==false){
                 array_unshift ($ret,$val['news_id']);
                 return $ret;
              }
       }
        return false;
}
Примерно так. Не проверял, так как лень вбивать массив.
 

rotoZOOM

ACM maniac
Фaнaт наставь на путь истинный. Я наверняка что-то не знаю или не догадываюсь или просто туплю. Известен такой массив, также известен news_id. Каким образом зная на входе эти данные проще всего получить искомый результат? Это все без сарказма.
 

Фанат

oncle terrible
Команда форума
чем не устраивает while ($var=$var['parent_id']) $parents[]=$var;

-~{}~ 03.11.08 11:15:

или я что ли туплю?
 

Фанат

oncle terrible
Команда форума
С точки зрения детей - просто многомерный.
Вообще, тут у меня два косяка. Во-первых, я неправильно понял задачу, а во-вторых и в реализаци тоже накосячил.

Я предполагал не спускаться вниз к news_id, а подниматься назад, к корням. Но если дано: массив и news_id, то да - только спускаться.
Приношу свои извинения.

-~{}~ 03.11.08 11:34:

я перепутал с бдой, когда пишут рекурсию, чтобы по id детки построить цепочку рдителей.
 

fixxxer

К.О.
Партнер клуба
а можно и спускаться без рекурсии.

hint:
while (..) {
...
$item = & $item['child'];
...
}
 

rotoZOOM

ACM maniac
fixxxer
1. В исходном массиве нет такого ключа, как 'child'.
2. Все равно придется искать этот $item, например той же рекурсией, а потом спускаться назад по стеку, почему бы с собой не захватить всех парентов?
3. Можешь привести пример такого массива, где бы твой кусок кода (точнее строчка) работала? Хотя бы два элемента root и child?
 

fixxxer

К.О.
Партнер клуба
в том-то и смысл, что его нет, тут он и создается.
привести не могу, мне влом :)
 
Сверху