【天天数据结构和算法】PHP实现二叉搜索树
1.通过分析普通数组、顺序数组、二分搜索树中查找数据,不难得知已下时间复杂度。
查找 | 插入 | 删除 | |
普通数组 | O(n) | O(n) | O(n) |
顺序数组 | O(logn) | O(n) | O(n) |
二叉搜索树 | O(logn) | O(logn) | O(logn) |
所以可以得出,二分搜索树的优势是高效的。
不仅如此,还可以方便的回答很多数据之间的关系问题:min,max,floor,ceil,rank(查找数据是当前数据的第几名),select(找到所有数据中第n个数据是什么)
2.下面我们就用PHP来实现二分搜索树
(1)在PHP中,类并没有结构体这个概念,所以我们将二分搜索树中的节点抽象成一个类Node.php,代码如下:
<?php /** * Created by PhpStorm. * User: jysdhr * Date: 2017/6/29 * Time: 17:35 * Description: */ class Node { /** * @var $key 当前结点的key * @var $value 当前节点的value * @var $left 当前节点的左子树 * @var $right 当前节点的右子树 */ public $key, $value, $left, $right; public function __construct($key, $value) { $this->key = $key; $this->value = $value; $this->left = $this->right = NULL; } }
(2)下面来实现BST.php(Binary Search Tree) 类文件
<?php /** * Created by PhpStorm. * User: jysdhr * Date: 2017/6/29 * Time: 17:46 * Description: */ include_once './Node.php'; class BST { /** * @var $count 当前二叉搜索树中的节点数 * @var $root 当前二叉搜索树 */ private $count,$root; public function __construct() { $this->root = NULL; $this->count = 0; } public function __destruct() { // TODO: Implement __destruct() method. $this->destroy($this->root); } public function size() { return $this->count; } public function isEmpty() { return $this->count == 0; } public function insert($key,$value) { $this->__insert($this->root,$key,$value); } public function contain($key) { return $this->__contain($this->root,$key); } public function search($key) { return $this->__search($this->root,$key); } public function preOrder() { $this->__preOrder($this->root); } public function inOrder() { $this->__inOrder($this->root); } public function afterOrder() { $this->__afterOrder($this->root); } private function destroy(&$node) { if ($node != NULL){ $this->destroy($node->left); $this->destroy($node->right); unset ($node); $this->count --; } } //对NODE为根的二叉树进行后序遍历 private function __afterOrder( &$node) { if ($node != NULL){ $this->__inOrder($node->left); $this->__inOrder($node->right); echo $node->key.'<br/>'; } } //对NODE为根的二叉树进行中序遍历 private function __inOrder(&$node) { if ($node != NULL){ $this->__inOrder($node->left); echo $node->key.'<br/>'; $this->__inOrder($node->right); } } //对Node为根的二叉搜索树进行前序遍历 private function __preOrder(&$node) { if ($node != NULL){ echo $node->key.'<br/>'; $this->__preOrder($node->left); $this->__preOrder($node->right); } } //在以node为根的二叉搜索树中查找key所对应的value private function __search(&$node,$key) { if ($node == NULL) return NULL; if ($key == $node->key) return $node->value; else if ($key < $node->key) return $this->__search($node->left,$key); else return $this->__search($node->right,$key); } //在以node为根的二叉搜索树中查找key是否存在 private function __contain(&$node,$key) { if ($node == NULL) return false; if ($key == $node->key) return true; else if ($key < $node->key) return $this->__contain($node->left,$key); else return $this->__contain($node->right,$key); } //向以node为根的二叉搜索树中,插入节点(key,value) //返回插入新节点后的二叉搜索树的根 private function __insert(&$node,$key,$value) { if ($node == NULL){ $this->count++; $node = new Node($key,$value); } if ($key == $node->key) $node->value = $value; else if ($key < $node->key) $this->__insert($node->left,$key,$value); else $this->__insert($node->right,$key,$value); } } //unit test $bst = new BST(); $bst->insert(1,'jiang'); $bst->insert(4,'jiang1'); $bst->insert(3,'jiang2'); $bst->preOrder();