认识和实现树到目前为止,我们对数据结构的探索只触及了线性部分。无论我们使用数组、链表、栈还是队列,它都是一种线性数据结构。我们已经看到了线性数据结构操作的复杂性,而大多数时候,插入和删除的复杂性可以用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。森林:森林由一组一棵或多棵不相交的树组成。遍历:这表示按特定顺序访问节点的过程。Key:用于查找,代表节点的值。使用PHP实现树到目前为止,我们已经了解了树的不同属性。如果我们将树与真实的例子进行比较,我们会发现组织结构或家谱可以用数字来表示。对于一个组织结构,有一个根节点,可以是公司的CEO,后面是CXO级别的员工,再后面是其他级别的员工。在这里,我们不限制特定节点的任何程度。这意味着一个节点可以有多个子节点。所以,这是一个节点结构,我们可以在其中定义节点属性、它的父节点和它的子节点:classTreeNode{public$data=null;公共$children=[];公共函数__construct(string$data=null){$this->data=$data;}publicfunctionaddChildren(TreeNode$treeNode){$this->children[]=$treeNode;我们可以看到我们已经声明了两个公共属性作为数据和孩子。我们还有一种方法可以将子节点添加到特定节点。在这里,我们只是在数组的末尾添加新的子节点。树是一种递归结构,可以帮助我们递归地构建树并递归地遍历树。现在我们有了节点,让我们构建一个树结构,它将定义树的根节点并遍历整个树。所以基本的树结构是这样的:classTree{public$root=null;公共函数__construct(TreeNode$treeNode){$this->root=$treeNode;}publicfunctiontraverse(TreeNode$treeNode,int$level=0){if($treeNode){echostr_repeat('-',$level)。$树节点->数据。PHP_EOL;foreach($treeNode->childrenas$child){$this->traverse($child,$level+1);}}}}前面的代码显示了一个简单的树类,我们可以在其中存储根节点引用并从任何节点遍历树。在遍历部分,我们访问每个子节点,然后立即递归调用遍历方法得到当前节点的子节点。我们传递一个级别并在节点名称的开头打印一个破折号(-),以便我们可以轻松理解子数据。require'./TreeNode.php';$ceo=newTreeNode('ceo');$tree=newTree($ceo);$cfo=newTreeNode('cfo');$cto=newTreeNode('cto');$cmo=newTreeNode('cmo');$coo=newTreeNode('coo');$ceo->addChildren($cfo);$ceo->addChildren($cto);$ceo->addChildren($cmo);$ceo->addChildren($coo);$seniorArchitect=newTreeNode("高级架构师");$softwareEngineer=newTreeNode("SoftwareEngineer");$userInterfaceDesigner=newTreeNode("用户界面设计师");$qualityAssuranceEngineer=newTreeNode("质量保证工程师");$cto->addChildren($seniorArchitect);$seniorArchitect->addChildren($softwareEngineer);$cto->addChildren($userInterfaceDesigner);$cto->addChildren($qualityAssuranceEngineer);$树->遍历($树->根);最终输出类似这样,完整代码可以看这里不同类型的树代码世界中有很多不同类型的树,一起来看看吧。二叉树二叉树是一种基本的树结构,其中二叉树的每个节点最多有两个子节点。二叉搜索树二叉搜索树(BST)是一种特殊类型的二叉树,其中节点以有序方式存储,即在任何给定点,节点值必须大于或等于左孩子的值节点的值小于右子节点节点的值。每个节点都必须满足这个属性,这是一个二叉搜索树。二叉搜索树算法总是比线性搜索好(它的时间复杂度是O(n)),这个我们后面会详细解释。自平衡二叉树自平衡二叉搜索树或高度平衡二叉搜索树是一种特殊类型的二叉搜索树,它试图通过自动调整自身来保持树的高度或层级尽可能小。左下图显示了一棵二叉搜索树,右图是一棵自平衡二叉搜索树:高度平衡的二叉树总是更好的选择,因为它比常规BST有利于更快的搜索操作。自平衡或高度平衡二叉搜索树有不同的实现方式。常见的有:AA树AVL树Red-blacktreeScapegoattreeOctree2-3treeTreap以后会陆续介绍,敬请期待。更多内容PHP基础数据结构专题系列目录:地址。主要用PHP语法总结基本的数据结构和算法。还有我们日常PHP开发中容易忽略的基础知识和现代PHP开发中规范、部署、优化的一些实用建议,以及对Javascript语言特性的深入研究。
