关于二叉搜索树的原理网上的资源就挺多的,而且情况有点小复杂,所以在这里我就不再陈述了,直接上代码吧:
#bst.php 文件 <!--?php /** * author:zhongjin * time:2016/10/20 11:53 * description: 二叉查找树 */ //结点 class Node { public $key; public $parent; public $left; public $right; public function __construct($key) { $this--->key = $key; $this->parent = NULL; $this->left = NULL; $this->right = NULL; } } //二叉搜索树 class Bst { public $root; /** * 初始化树结构 * @param $arr 初始化树结构的数组 * @return null */ public function init($arr) { $this->root = new Node($arr[0]); for ($i = 1; $i < count($arr); $i++) { $this->Insert($arr[$i]); } } /** * (对内)中序遍历 * @param $root (树或子树的)根节点 * @return null */ private function mid_order($root) { if ($root != NULL) { $this->mid_order($root->left); echo $root->key . " "; $this->mid_order($root->right); } } /** * (对外)中序遍历 * @param null * @return null */ public function MidOrder() { $this->mid_order($this->root); } /** * 查找树中是否存在$key对应的节点 * @param $key 待搜索数字 * @return $key对应的节点 */ function search($key) { $current = $this->root; while ($current != NULL) { if ($current->key == $key) { return $current; } elseif ($current->key > $key) { $current = $current->left; } else { $current = $current->right; } } return $current; } /** * 查找树中的最小关键字 * @param $root 根节点 * @return 最小关键字对应的节点 */ function search_min($root) { $current = $root; while ($current->left != NULL) { $current = $current->left; } return $current; } /** * 查找树中的最大关键字 * @param $root 根节点 * @return 最大关键字对应的节点 */ function search_max($root) { $current = $root; while ($current->right != NULL) { $current = $current->right; } return $current; } /** * 查找某个$key在中序遍历时的直接前驱节点 * @param $x 待查找前驱节点的节点引用 * @return 前驱节点引用 */ function predecessor($x) { //左子节点存在,直接返回左子节点的最右子节点 if ($x->left != NULL) { return $this->search_max($x->left); } //否则查找其父节点,直到当前结点位于父节点的右边 $p = $x->parent; //如果x是p的左孩子,说明p是x的后继,我们需要找的是p是x的前驱 while ($p != NULL && $x == $p->left) { $x = $p; $p = $p->parent; } return $p; } /** * 查找某个$key在中序遍历时的直接后继节点 * @param $x 待查找后继节点的节点引用 * @return 后继节点引用 */ function successor($x) { if ($x->left != NULL) { return $this->search_min($x->right); } $p = $x->parent; while ($p != NULL && $x == $p->right) { $x = $p; $p = $p->parent; } return $p; } /** * 将$key插入树中 * @param $key 待插入树的数字 * @return null */ function Insert($key) { if (!is_null($this->search($key))) { throw new Exception('结点' . $key . '已存在,不可插入!'); } $root = $this->root; $inode = new Node($key); $current = $root; $prenode = NULL; //为$inode找到合适的插入位置 while ($current != NULL) { $prenode = $current; if ($current->key > $inode->key) { $current = $current->left; } else { $current = $current->right; } } $inode->parent = $prenode; //如果$prenode == NULL, 则证明树是空树 if ($prenode == NULL) { $this->root = $inode; } else { if ($inode->key < $prenode->key) { $prenode->left = $inode; } else { $prenode->right = $inode; } } //return $root; } /** * 在树中删除$key对应的节点 * @param $key 待删除节点的数字 * @return null */ function Delete($key) { if (is_null($this->search($key))) { throw new Exception('结点' . $key . "不存在,删除失败!"); } $root = $this->root; $dnode = $this->search($key); if ($dnode->left == NULL || $dnode->right == NULL) { #如果待删除结点无子节点或只有一个子节点,则c = dnode $c = $dnode; } else { #如果待删除结点有两个子节点,c置为dnode的直接后继,以待最后将待删除结点的值换为其后继的值 $c = $this->successor($dnode); } //无论前面情况如何,到最后c只剩下一边子结点 if ($c->left != NULL) { $s = $c->left; } else { $s = $c->right; } if ($s != NULL) { #将c的子节点的父母结点置为c的父母结点,此处c只可能有1个子节点,因为如果c有两个子节点,则c不可能是dnode的直接后继 $s->parent = $c->parent; } if ($c->parent == NULL) { #如果c的父母为空,说明c=dnode是根节点,删除根节点后直接将根节点置为根节点的子节点, 此处dnode是根节点,且拥有两个子节点,则c是dnode的后继结点,c的父母就不会为空,就不会进入这个if $this->root = $s; } else if ($c == $c->parent->left) { #如果c是其父节点的左右子节点,则将c父母的左右子节点置为c的左右子节点 $c->parent->left = $s; } else { $c->parent->right = $s; } #如果c!=dnode,说明c是dnode的后继结点,交换c和dnode的key值 if ($c != $dnode) { $dnode->key = $c->key; } #返回根节点 // return $root; } /** * (对内)获取树的深度 * @param $root 根节点 * @return 树的深度 */ private function getdepth($root) { if ($root == NULL) { return 0; } $dl = $this->getdepth($root->left); $dr = $this->getdepth($root->right); return ($dl > $dr ? $dl : $dr) + 1; } /** * (对外)获取树的深度 * @param null * @return null */ public function Depth() { return $this->getdepth($this->root); } }
调试的时候你们可以调用中序遍历来做,我在上一篇博客中提供了PHP实现的二叉树图形化,有了视觉上的帮助就能更好的帮助我们进行调试,详细大家可以访问我的上一篇博客:《利用PHP实现二叉树的图形显示》
以上就是PHP二叉树(一):二叉搜索树的内容,更多相关内容请关注PHP中文网(www.php.cn)!

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。

PHP中使用clone关键字创建对象副本,并通过\_\_clone魔法方法定制克隆行为。1.使用clone关键字进行浅拷贝,克隆对象的属性但不克隆对象属性内的对象。2.通过\_\_clone方法可以深拷贝嵌套对象,避免浅拷贝问题。3.注意避免克隆中的循环引用和性能问题,优化克隆操作以提高效率。

PHP适用于Web开发和内容管理系统,Python适合数据科学、机器学习和自动化脚本。1.PHP在构建快速、可扩展的网站和应用程序方面表现出色,常用于WordPress等CMS。2.Python在数据科学和机器学习领域表现卓越,拥有丰富的库如NumPy和TensorFlow。

HTTP缓存头的关键玩家包括Cache-Control、ETag和Last-Modified。1.Cache-Control用于控制缓存策略,示例:Cache-Control:max-age=3600,public。2.ETag通过唯一标识符验证资源变化,示例:ETag:"686897696a7c876b7e"。3.Last-Modified指示资源最后修改时间,示例:Last-Modified:Wed,21Oct201507:28:00GMT。

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP是一种服务器端脚本语言,用于动态网页开发和服务器端应用程序。1.PHP是一种解释型语言,无需编译,适合快速开发。2.PHP代码嵌入HTML中,易于网页开发。3.PHP处理服务器端逻辑,生成HTML输出,支持用户交互和数据处理。4.PHP可与数据库交互,处理表单提交,执行服务器端任务。

PHP在过去几十年中塑造了网络,并将继续在Web开发中扮演重要角色。1)PHP起源于1994年,因其易用性和与MySQL的无缝集成成为开发者首选。2)其核心功能包括生成动态内容和与数据库的集成,使得网站能够实时更新和个性化展示。3)PHP的广泛应用和生态系统推动了其长期影响,但也面临版本更新和安全性挑战。4)近年来的性能改进,如PHP7的发布,使其能与现代语言竞争。5)未来,PHP需应对容器化、微服务等新挑战,但其灵活性和活跃社区使其具备适应能力。

PHP的核心优势包括易于学习、强大的web开发支持、丰富的库和框架、高性能和可扩展性、跨平台兼容性以及成本效益高。1)易于学习和使用,适合初学者;2)与web服务器集成好,支持多种数据库;3)拥有如Laravel等强大框架;4)通过优化可实现高性能;5)支持多种操作系统;6)开源,降低开发成本。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版

Atom编辑器mac版下载
最流行的的开源编辑器

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器