【天天数据结构和算法】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();

 

posted @ 2017-06-30 16:20  jysdhr  阅读(948)  评论(0编辑  收藏  举报