nicmart/tree

一个基本但灵活的php树形数据结构和流畅的树形构建实现。

维护者

详细信息

github.com/nicmart/Tree

源代码

问题

安装次数: 11,859,407

依赖: 31

建议者: 0

安全性: 0

星星: 568

关注者: 15

分支: 62

开放问题: 5

0.8.0 2023-12-02 13:24 UTC

README

Integrate Release

Code Coverage Type Coverage

Latest Stable Version Total Downloads Monthly Downloads

In Tree you can find a basic but flexible tree data structure for php together with and an handful Builder class, that enables you to build tree in a fluent way.

树形数据结构

Tree\Node\NodeInterface 接口抽象了树节点的概念。在 Tree 中,一个节点本质上包含两个东西:一组子节点(实现相同的 NodeInterface 接口)和一个值。

另一方面,Tree\Node\Node 为该接口提供了一个直接的实现。

创建一个节点

use Tree\Node\Node;

$node = new Node('foo');

获取和设置节点的值

每个节点都有一个值属性,可以是任何 PHP 值。

$node->setValue('my value');
echo $node->getValue(); //Prints 'my value'

添加一个或多个子节点

$child1 = new Node('child1');
$child2 = new Node('child2');

$node
    ->addChild($child1)
    ->addChild($child2);

删除一个子节点

$node->removeChild($child1);

获取所有子节点的数组

$children = $node->getChildren();

覆盖子节点集

$node->setChildren([new Node('foo'), new Node('bar')]);

删除所有子节点

$node->removeAllChildren();

获取节点是否是叶子节点

叶子节点是没有子节点的节点。

$node->isLeaf();

获取节点是否是子节点

子节点是具有父节点的节点。

$node->isChild();

获取节点的父节点

父节点的引用由子修改方法自动管理

$root->addChild($node = new Node('child'));
$node->getParent(); // Returns $root

获取节点的祖先节点

$root = (new Node('root'))
    ->addChild($child = new Node('child'))
    ->addChild($grandChild = new Node('grandchild'))
;

$grandchild->getAncestors(); // Returns [$root, $child]

相关方法

  • getAncestorsAndSelf 获取包括当前节点在内的节点祖先。

获取节点的根节点

$root = $node->root();

获取节点的邻居节点

$root = (new Node('root'))
    ->addChild($child1 = new Node('child1'))
    ->addChild($child2 = new Node('child2'))
    ->addChild($child3 = new Node('child3'))
;

$child2->getNeighbors(); // Returns [$child1, $child3]

相关方法

  • getNeighborsAndSelf 获取当前节点及其本身的邻居节点。

获取树中节点的数量

$node->getSize();

获取节点的深度

$node->getDepth();

获取节点的身高

$node->getHeight();

构建器

构建器提供了一种方便的构建树的方法。它由 Builder 类提供,但你也可以实现自己的构建器,创建一个 BuilderInterface 类的实现。

示例

让我们看看如何构建以下树,其中节点的标签表示节点的值

       A
      / \
     B   C
        /|\
       D E F
      /|
     G H

以下是代码

$builder = new Tree\Builder\NodeBuilder;

$builder
    ->value('A')
    ->leaf('B')
    ->tree('C')
        ->tree('D')
            ->leaf('G')
            ->leaf('H')
            ->end()
        ->leaf('E')
        ->leaf('F')
        ->end()
;

$nodeA = $builder->getNode();

示例应该是自解释的,但这里简要描述一下上述使用的方法。

Builder::value($value)

将当前节点的值设置为 $value

Builder::leaf($value)

向当前节点添加一个新子节点,其值为 $value

Builder::tree($value)

向当前节点添加一个新子节点,其值为 $value,并将新节点设置为构建器的当前节点。

Builder::end()

返回到 tree 方法调用之前的构建器上下文,即使构建器向上移动一个级别。

Builder::getNode()

返回当前节点。

遍历树

产出

您可以使用 YieldVisitor 获取树的产出(即前序遍历中的叶子节点列表)。

例如,如果 $node 是上面构建的树,那么

use Tree\Visitor\YieldVisitor;

$visitor = new YieldVisitor;

$yield = $node->accept($visitor);
// $yield will contain nodes B, G, H, E, F

前序遍历

您可以使用前序遍历遍历树

use Tree\Visitor\PreOrderVisitor;

$visitor = new PreOrderVisitor;

$yield = $node->accept($visitor);
// $yield will contain nodes A, B, C, D, G, H, E, F

后序遍历

您可以使用后序遍历遍历树

use Tree\Visitor\PostOrderVisitor;

$visitor = new PostOrderVisitor;

$yield = $node->accept($visitor);
// $yield will contain nodes B, G, H, D, E, F, C, A

安装

运行

$ composer require nicmart/tree

测试

phpunit

变更日志

请参阅 CHANGELOG.md

贡献

请查看CONTRIBUTING.md

许可协议

此软件包使用MIT许可协议进行许可。

请查看LICENSE.md