PHP实现 二叉查找树

<?php
/**
 * Created by PhpStorm.
 * User: baimayou
 * Date: 19-3-20
 * Time: 下午6.00
 * 二叉查找树
 * 二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值
 */
//定义二叉树的节点
class Node{
    public $left = null;
    public $right = null;
    public $data = '';
    public function __construct($data){
        $this->data = $data;
    }

}
//二叉查找树的添加
function buildSearchTree($tree,$value){
    if($tree == null){
        $tree = new Node($value);
    }
    $newNode = new Node($value);
    while($tree != null){
        if($tree->data > $value){
            if($tree->left == null){
                $tree->left = $newNode;
                return;
            }
            $tree = $tree->left;
        }else{
            if($tree->right == null){
                $tree->right =$newNode;
                return;
            }
            $tree = $tree->right;
        }
    }
}
//二叉查找树的删除
/**
 * 第一种情况是,如果要删除的节点没有子节点,我们只需要直接将父节点中,指向要删除节点的指针置为 null。
 * 第二种情况是,如果要删除的节点只有一个子节点(只有左子节点或者右子节点),我们只需要更新父节点中,指向要删除节点的指针,
 *      让它指向要删除节点的子节点就可以了
 * 第三种情况是,如果要删除的节点有两个子节点,这就比较复杂了。
 *      我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上。然后再删除掉这个最小节点,
 *      因为最小节点肯定没有左子节点(如果有左子结点,那就不是最小节点了)
 *
 * 注意:注意指针的位置 和 树的结构,对象的赋值,值地址的赋值,也会改变对象
 **/
//找到该节点并删除
function deleteBst(&$tree,$value){
    if(is_null($tree)){
        return false;
    }
    if($tree->data == $value){
        return delete($tree);
    }elseif ($tree->data < $value){
        deleteBst($tree->right,$value);
    }else{
        deleteBst($tree->left,$value);
    }
}
//调整删除后树的形态
function delete(&$biTree) {
    if ($biTree->left === null) {   //删除的节点有唯一右子树
        $biTree = $biTree->right;
    } else if ($biTree->right === null) { //删除的节点有唯一左子树
        $biTree = $biTree->left;
    } else {    //删除的节点有左右子树
        //找到要删除的节点左子树的最右节点然后删除 (或者右子树的最左节点)
        $parNode = $biTree;
        $delNode = $biTree->left;
        while (!is_null($delNode->right)) {
            $parNode = $delNode;
            $delNode = $delNode->right;
        }
        $biTree->data = $delNode->data;
//        if ($biTree == $parNode) {
//            $parNode->left = $delNode->left;
//        } else {
//            $parNode->right = $delNode->left;
//        }
    }
}
function preOrder($tree){
    if($tree != null){
        echo $tree->data;
        preOrder($tree->left);
        preOrder($tree->right);
    }
}
$a = new Node('3');
buildSearchTree($a,'6');
buildSearchTree($a,'2');
buildSearchTree($a,'1');
buildSearchTree($a,'5');
buildSearchTree($a,'4');
buildSearchTree($a,'7');
buildSearchTree($a,'8');
buildSearchTree($a,'9');
preOrder($a);
deleteBst($a,8);
echo "<br>";
preOrder($a);


上一篇:实验2:二叉树的创建和遍历


下一篇:2015年第六届蓝桥杯决赛Java本科B组试题解析