二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。
一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。
 
 
<?php
/**  * 二叉树的定义  */
class BinaryTree {
protected $key = NULL;      //  当前节点的值
protected $left = NULL;     //  左子树
protected $right = NULL;    //  右子树
/**      * 以指定的值构造二叉树,并指定左右子树      *
* @param mixed $key 节点的值.
* @param mixed $left 左子树节点.
* @param mixed $right 右子树节点.
*/
public function __construct( $key = NULL, $left = NULL, $right = NULL) {
       $this->key = $key;
        if ($key === NULL) {
            $this->left = NULL;
            $this->right = NULL;
        }
        elseif ($left === NULL) {
            $this->left = new BinaryTree();
            $this->right = new BinaryTree();
        }
        else {
            $this->left = $left;
            $this->right = $right;
        }
    }
 
    /**
     * 析构方法.
     */
    public function __destruct() {
        $this->key = NULL;
        $this->left = NULL;
        $this->right = NULL;
    }
 
    /**
    * 清空二叉树.
    **/
    public function purge () {
        $this->key = NULL;
        $this->left = NULL;
        $this->right = NULL;
    }
 
    /**
     * 测试当前节点是否是叶节点.
     *
     * @return boolean 如果节点非空并且有两个空的子树时为真,否则为假.
     */
    public function isLeaf() {
        return !$this->isEmpty() &&
            $this->left->isEmpty() &&
            $this->right->isEmpty();
    }
 
    /**
     * 测试节点是否为空
     *
     * @return boolean 如果节点为空返回真,否则为假.
     */
    public function isEmpty() {
        return $this->key === NULL;
    }
 
    /**
     * Key getter.
     *
     * @return mixed 节点的值.
     */
    public function getKey() {
        if ($this->isEmpty()) {
            return false;
        }
        return $this->key;
    }
 
    /**
     * 给节点指定Key值,节点必须为空
     *
     * @param mixed $object 添加的Key值.
     */
    public function attachKey($obj) {
        if (!$this->isEmpty())
            return false;
        $this->key = $obj;
        $this->left = new BinaryTree();
        $this->right = new BinaryTree();
    }
 
    /**
     * 删除key值,使得节点为空.
     */
    public function detachKey() {
        if (!$this->isLeaf())
            return false;
        $result = $this->key;
        $this->key = NULL;
        $this->left = NULL;
        $this->right = NULL;
        return $result;
    }
 
    /**
     * 返回左子树
     *
     * @return object BinaryTree 当前节点的左子树.
     */
    public function getLeft() {
        if ($this->isEmpty())
            return false;
        return $this->left;
    }
 
    /**
     * 给当前结点添加左子树
     *
     * @param object BinaryTree $t 给当前节点添加的子树.
     */
    public function attachLeft(BinaryTree $t) {
        if ($this->isEmpty() || !$this->left->isEmpty())
            return false;
        $this->left = $t;
    }
 
    /**
     * 删除左子树
     *
     * @return object BinaryTree  返回删除的左子树.
     */
    public function detachLeft() {
        if ($this->isEmpty())
            return false;
        $result = $this->left;
        $this->left = new BinaryTree();
        return $result;
    }
 
    /**
     * 返回当前节点的右子树
     *
     * @return object BinaryTree 当前节点的右子树.
     */
    public function getRight() {
        if ($this->isEmpty())
            return false;
        return $this->right;
    }
 
    /**
     * 给当前节点添加右子树
     *
     * @param object BinaryTree $t 需要添加的右子树.
     */
    public function attachRight(BinaryTree $t) {
        if ($this->isEmpty() || !$this->right->isEmpty())
            return false;
        $this->right = $t;
    }
 
    /**
     * 删除右子树,并返回此右子树
     * @return object BinaryTree 删除的右子树.
     */
    public function detachRight() {
        if ($this->isEmpty ())
            return false;
        $result = $this->right;
        $this->right = new BinaryTree();
        return $result;
    }
 
    /**
     * 先序遍历
     */
    public function preorderTraversal() {
        if ($this->isEmpty()) {
            return ;
        }
        echo ' ', $this->getKey();
        $this->getLeft()->preorderTraversal();
        $this->getRight()->preorderTraversal();
    }
 
    /**
     * 中序遍历
     */
    public function inorderTraversal() {
        if ($this->isEmpty()) {
            return ;
        }
        $this->getLeft()->preorderTraversal();
        echo ' ', $this->getKey();
        $this->getRight()->preorderTraversal();
    }
 
    /**
     * 后序遍历
     */
    public function postorderTraversal() {
        if ($this->isEmpty()) {
            return ;
        }
        $this->getLeft()->preorderTraversal();
        $this->getRight()->preorderTraversal();
        echo ' ', $this->getKey();
    }
}
 
/**
 * 二叉排序树的PHP实现
 */
 
class BST extends BinaryTree {
  /**
     * 构造空的二叉排序树
     */
    public function __construct() {
        parent::__construct(NULL, NULL, NULL);
    }
 
    /**
     * 析构
     */
    public function __destruct() {
        parent::__destruct();
    }
 
    /**
     * 测试二叉排序树中是否包含参数所指定的值
     *
     * @param mixed $obj 查找的值.
     * @return boolean True 如果存在于二叉排序树中则返回真,否则为假期
     */
    public function contains($obj) {
        if ($this->isEmpty())
            return false;
        $diff = $this->compare($obj);
        if ($diff == 0) {
            return true;
        }elseif ($diff < 0)             return $this->getLeft()->contains($obj);
        else
            return $this->getRight()->contains($obj);
    }
 
    /**
     * 查找二叉排序树中参数所指定的值的位置
     *
     * @param mixed $obj 查找的值.
     * @return boolean True 如果存在则返回包含此值的对象,否则为NULL
     */
    public function find($obj) {
        if ($this->isEmpty())
            return NULL;
        $diff = $this->compare($obj);
        if ($diff == 0)
            return $this->getKey();
        elseif ($diff < 0)             return $this->getLeft()->find($obj);
        else
            return $this->getRight()->find($obj);
    }
 
    /**
     * 返回二叉排序树中的最小值
     * @return mixed 如果存在则返回最小值,否则返回NULL
     */
    public function findMin() {
        if ($this->isEmpty ())
            return NULL;
        elseif ($this->getLeft()->isEmpty())
            return $this->getKey();
        else
            return $this->getLeft()->findMin();
    }
 
    /**
     * 返回二叉排序树中的最大值
     * @return mixed 如果存在则返回最大值,否则返回NULL
     */
    public function findMax() {
        if ($this->isEmpty ())
            return NULL;
        elseif ($this->getRight()->isEmpty())
            return $this->getKey();
        else
            return $this->getRight()->findMax();
    }
 
    /**
     * 给二叉排序树插入指定值
     *
     * @param mixed $obj 需要插入的值.
     * 如果指定的值在树中存在,则返回错误
     */
    public function insert($obj) {
        if ($this->isEmpty()) {
            $this->attachKey($obj);
        } else {
            $diff = $this->compare($obj);
            if ($diff == 0)
                die('argu error');
            if ($diff < 0)                 $this->getLeft()->insert($obj);
            else
                $this->getRight()->insert($obj);
        }
        $this->balance();
    }
 
 /**
     * 从二叉排序树中删除指定的值
     *
     * @param mixed $obj 需要删除的值.
     */
    public function delete($obj) {
        if ($this->isEmpty ())
            die();
 
        $diff = $this->compare($obj);
        if ($diff == 0) {
            if (!$this->getLeft()->isEmpty()) {
                $max = $this->getLeft()->findMax();
                $this->key = $max;
                $this->getLeft()->delete($max);
            }
            elseif (!$this->getRight()->isEmpty()) {
                $min = $this->getRight()->findMin();
                $this->key = $min;
                $this->getRight()->delete($min);
            } else
                $this->detachKey();
        } else if ($diff < 0)                 $this->getLeft()->delete($obj);
            else
                $this->getRight()->delete($obj);
        $this->balance();
    }
 
    public function compare($obj) {
        return $obj - $this->getKey();
    }
 
    /**
     * Attaches the specified object as the key of this node.
     * The node must be initially empty.
     *
     * @param object IObject $obj The key to attach.
     * @exception IllegalOperationException If this node is not empty.
     */
    public function attachKey($obj) {
        if (!$this->isEmpty())
            return false;
        $this->key = $obj;
        $this->left = new BST();
        $this->right = new BST();
    }
 
    /**
     * Balances this node.
     * Does nothing in this class.
     */
    protected function balance () {}
 
    /**
     * Main program.
     *
     * @param array $args Command-line arguments.
     * @return integer Zero on success; non-zero on failure.
     */
    public static function main($args) {
        printf("BinarySearchTree main program.\n");
        $root = new BST();
        foreach ($args as $row) {
            $root->insert($row);
        }
        return $root;
    }
}
 
$root = BST::main(array(50, 3, 10, 5, 100, 56, 78));
echo $root->findMax();
$root->delete(100);
echo $root->findMax();

  

php二叉树算法的更多相关文章

  1. JavaScript实现二叉树算法

    二叉树的遍历方式 分别为中序遍历(左子树->当前节点->右子树).前序遍历(当前节点->左子树->右子树).后序遍历(左子树->右子树->当前节点).下面使用Jav ...

  2. JS数据结构与算法 - 剑指offer二叉树算法题汇总

    ❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...

  3. JS - 二叉树算法实现与遍历 (更新中...)

    一.关于二叉树: 截图来自:https://segmentfault.com/a/1190000000740261 温馨提示:学习以及使用二叉树概念,心中永远有这么一个图,对于理解和接受二叉树有很大的 ...

  4. js 二叉树算法

    //生成二叉树 function binarySearchTree() { let Node = function(key) { this.key = key; this.left = null; t ...

  5. Javascritp 数据结构和二叉树算法

    1,所有圆圈都是一个节点,里面的数字就是节点的值.8上面没有父节点,那么8就是根节点,而4,7,13没有子节点了,称之为叶子结点.其他的称之为:中间结点. 2,8节点是3和10的父节点,3是8的左孩子 ...

  6. 面试常见二叉树算法题集锦-Java实现

    1.求二叉树的深度或者说最大深度 /* ***1.求二叉树的深度或者说最大深度 */ public static int maxDepth(TreeNode root){ if(root==null) ...

  7. C#使用二叉树算法设计一个无限分级的树表

    效果图: 数据库: 操作树的示意图: 控制器代码: using Dw.Business; using Dw.Entity; using Dw.Utilities; using System; usin ...

  8. java版二叉树算法实现

    import java.util.ArrayList; class BinaryTree { private static class TreeNode { int data; TreeNode le ...

  9. [二叉树算法]关于判断是否为BST的算法

    //判断是否为BST 搜索树==二叉排序树 1.递归知最大最小值.2.先中序判是否单调 bool IsValidBST(BTNode *p,int low,int high){ if(p==NULL) ...

随机推荐

  1. PHP学习笔记03——函数

    <!DOCTYPE unspecified PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www. ...

  2. UVALive 5532 King(差分约束,spfa)

    题意:假设一个序列S有n个元素,现在有一堆约束,限制在某些连续子序列之和上,分别有符号>和<.问序列S是否存在?(看题意都看了半小时了!) 注意所给的形式是(a,b,c,d),表示:区间之 ...

  3. android事件系列-onTouch事件与手势操作

    提示记忆:应用流程:在Activity中对控件执行 view.setOnTouchListener( OnTouchListener i);实现里面的OnTouchListener 接口中的方法,重点 ...

  4. 【Java】MD5加密

    package sdfg; import java.math.BigInteger; import java.security.MessageDigest; import java.security. ...

  5. python开发学习-day01 (python安装与版本、字符串、字典、运算符、文件)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  6. Python学习2-列表和元组

    Python学习2-列表和元组 标签(空格分隔): 列表 元组 在Python中,最基本的数据结构是序列(sequence).序列中的每个元素被分配一个序号--即元素的位置,也称为索引.索引从0开始. ...

  7. MySQL与Oracle 差异比较之六触发器

    触发器 编号 类别 ORACLE MYSQL 注释 1 创建触发器语句不同 create or replace trigger TG_ES_FAC_UNIT  before insert or upd ...

  8. Arduino报错

    avrdude: stk500_recv(): programmer is not respondingavrdude: stk500_getsync() attempt 1 of 10: not i ...

  9. uglifyjs使用

    1.安装Nodejs:去这里下载并安装. 2.打开cmd,运行npm,node应该会有输出东西 3.如果在window上运行Node.js的npm报Error: ENOENT, stat 'C:\Us ...

  10. android操作SQLite

    一.SQLite SQLite是一种转为嵌入式设备设计的轻型数据库,其只有五种数据类型,分别是: NULL: 空值 INTEGER: 整数 REAL: 浮点数 TEXT: 字符串 BLOB: 大数据 ...