Возврат экземпляра самого узла в классе дерева php - PullRequest
0 голосов
/ 20 июля 2011

Итак, я пытаюсь создать древовидную структуру в PHP. Я не знаю, возможно ли это, и я не настолько хорош в PHP, так что это сложно для меня.

Код, который у меня пока есть (только важные вещи, лишний код был вырезан):

abstract class tree_node {
    protected $_child_refs = array();

    abstract public function add_child($arg);

    public function count() {
        return count($this->_child_refs);
    }

    public function get_deepest_children() {
        if ($this->count() === 0) {
            return $this;
        } else {
            foreach ($this->_child_refs as $child_ref) {
                $deepest[] = $child_ref->get_deepest_children();
            }
        }
    }

    abstract public function __construct();
}

class data_node extends tree_node {
    private $_data = "";

    public function add_child($data) {
        $new_child = new data_node($data);
        $this->_child_refs[] = $new_child;
    }

    public function __construct($data) {
        $this->_data = $data;
    }
}

$foo = new data_node("foo");
$foo->add_child("bar");

var_dump($foo->get_deepest_children());

Этот код должен возвращать data_node с "bar" в качестве данных, но вместо этого я получаю NULL. Что не так с «вернуть $ это»? Разве это не правильный способ вернуть экземпляр самого класса?

Кроме того, не стесняйтесь критиковать этот код / ​​скажите мне, что я делаю это совершенно неправильно. Я хочу отделить функции дерева от функций, специфичных для данных, хранящихся в дереве, поэтому я разделил их на два класса, но если вы считаете, что это плохая идея, скажите мне.

Ответы [ 2 ]

0 голосов
/ 20 июля 2011

Ваш get_deepest_children не всегда возвращает один и тот же тип значения. В базовом случае он возвращает объект узла, в других случаях он расширяет список $deepest, но не возвращает никакого значения.

<?php
public function get_deepest_children() {
    if ($this->count() === 0) {
        return $this;
    } else {
        foreach ($this->_child_refs as $child_ref) {
            $deepest[] = $child_ref->get_deepest_children();
        }
    }
}

Я бы изменил это так:

<?php
public function get_deepest_children() {
    if ($this->count() === 0) {
        return Array($this);
    } else {
        $deepest = Array();

        foreach ($this->_child_refs as $child_ref) {
            $deepest = array_merge($deepest, $child_ref->get_deepest_children());
        }

        return $deepest;
    }
}

Вы должны увидеть, как теперь он всегда возвращает массив всех самых глубоких узлов (обычно называемых конечных узлов ) ниже / включая текущий. Таким образом, мы можем array_merge последовательные результаты, чтобы получить окончательные результаты.

0 голосов
/ 20 июля 2011

Это:

public function get_deepest_children() {
    if ($this->count() === 0) {
        return $this;
    } else {
        foreach ($this->_child_refs as $child_ref) {
            $deepest[] = $child_ref->get_deepest_children();
        }
    }
}

Должно быть что-то вроде этого:

public function get_deepest_children() {
    if ($this->count() === 0) {
        return array($this);
    }
    $deepest = array();
    foreach ($this->_child_refs as $child_ref) {
        $deepest = array_merge($deepest,$child_ref->get_deepest_children());
    }
    return $deepest;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...