专栏名称: 狗厂
目录
相关文章推荐
Kevin在纽约  ·  你喜欢图一的城景房,还是图二的乡村风? . ... ·  23 小时前  
最高人民检察院  ·  作废公章惹官司,单位该担什么责? ·  2 天前  
最高人民法院  ·  最根本的还是“不想腐” ·  3 天前  
51好读  ›  专栏  ›  狗厂

PHP面试:说说你理解的二叉树吧

狗厂  · 掘金  ·  · 2018-07-16 05:43

正文

理解和实现树

迄今为止,我们对数据结构的探索仅触及线性部分。无论我们使用数组、链表、栈还是队列,都是线性数据结构。我们已经看到了线性数据结构操作的复杂性,大多数时候,插入和删除的复杂度可以用O(1)来表示。搜索有点复杂,需要O(n)复杂度。唯一的例外是PHP数组,它实际上是哈希表,如果索引或键在这样的以这样的方式管理,则可以达到O(1)的复杂度。为了解决这个问题,我们可以使用分层数据结构,而不是线性数据结构。分层数据可以很好地解决线性数据结构难以解决的许多问题。

每当我们谈论家庭族谱、组织结构和网络连接图时,我们实际上都在谈论分层数据。树是一种特殊的抽象数据类型(ADT)。不同于 链表 ,树是分层的。

树的定义和特点

树是由边连接的节点或顶点的分层集合。树不能有循环,并且只有节点和它的下降节点或子节点之间存在边。同一父级的两个子节点在它们之间不能有任何边。每个节点可以有一个父节点除非是顶部节点,也称为根节点。每棵树只能有一个根节点。每个节点可以有零个或多个子节点。在下面的图中,A是根节点,B、C和D是A的子节点。我们也可以说,A是B、C、D的父节点。B、C和D被称为兄弟姐妹,因为它们是来自同一父节点A。

没有任何子节点的节点称为叶子。在前面的图中,K、L、F、G、M、I和J是叶子节点。叶子节点也称为外部节点或终端节点。除根以外的节点具有至少一个子节点,称为内部节点。这里,B、C、D、E和H是内部节点。这里是一些其他常用的术语,用于描述树的数据结构:

后裔:这是一个可以通过重复的程序从父节点到达的节点。例如,M是前一个图中C的后裔。

祖先:这是一个可以通过重复方式从子节点到达父节点的节点。例如,B是L的祖先。

度:特定父节点的子节点的总数被称为它的度数。在我们的例子中,A有3度,B有1度,C有度3,D有度2。

路径:从源节点到目标节点的节点和边的序列称为两个节点之间的路径。路径的长度是路径中节点的数目。A到M之间的路径是A-C-H-M,路径的长度为4。

节点的高度:节点的高度由节点与最深节点之间的边数决定。例如,节点B的高度为2。

层次:层次代表节点的生成。如果父节点处于层次N,则其子节点将位于N+ 1层次。因此,该层次由节点和根之间的边数定义。

A在0层

B,C和D是1层

E,F,G,H,I,J是2层

K,L,M都在第3层。

树的高度:树的高度是由它的根节点的高度定义的。上图树的高度是3。

子树:在树结构中,每个孩子递归地形成子树。换句话说,树由许多子树组成。例如,B和E、K和L构成了一个子树,E、K和 L构成了一个子树,每个不同的阴影中都对它们进行了识别。

深度:节点的深度由节点和根节点之间的边数决定。例如,H的深度是2,L的深度是3。

森林:森林是由一组或更多的不相交的树组成。

遍历:这表示按特定顺序访问节点的过程。

键:用于搜索,表示节点的值。

使用PHP实现树

到目前为止,我们已经了解了树的不同属性。如果我们对比树和现实的例子,我们发现组织结构或族谱树可以用数表示。对于一个组织结构,有一个根节点可以是公司的CEO,其次是CXO级别的员工,其次是其他级别的员工。这里,我们不限制特定节点的任何度。这意味着一个节点可以有多个子节点。因此,下面是一个节点结构,我们可以定义节点属性、它的父节点和它的子节点:

class TreeNode
{
    public $data = null;

    public $children = [];

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

    public function addChildren(TreeNode $treeNode)
    {
        $this->children[] = $treeNode;
    }
}

我们可以看到我们声明了两个公共属性分别为数据和孩子。我们还有一个方法将孩子添加到一个特定的节点。这里,我们只是在数组末尾添加新的子节点。树是递归结构,它将帮助我们递归地构建树,并递归地遍历树。







请到「今天看啥」查看全文