PHP实现二叉树和测试

10 篇文章 0 订阅
6 篇文章 0 订阅
<?php


class TreeNode
{
    private $value;
    private $leftChild;
    private $rightChild;

    public function __construct($value,$leftChild=null,$rightChild=null)
    {
        $this->value = $value;
        $this->leftChild = $leftChild;
        $this->rightChild = $rightChild;
    }

    public function getValue(){
        return $this->value;
    }

    public function getLeftChild(){
        return $this->leftChild;
    }

    public function getRightChild(){
        return $this->rightChild;
    }

    public function setLeftChild($childNode){
        return $this->leftChild = $childNode;
    }

    public function setRightChild($childNode){
        return $this->rightChild = $childNode;
    }

}

 

<?php

include "TreeNode.php";

class BinaryTree
{

    public $root = null;

    public function __construct()
    {

    }

    /**
     * 插入
     * 查找根节点是否存在,如果不存在,那么直接插入
     * 如果存在,比较节点大小,如果比当前节点值小,那么获取节点左子节点,如果不存在,那么插入,如果存在,递归调用插入函数继续往下找
     * 如果比当前节点值大,那么获取节点右子节点,如果不存在,那么插入,如果存在,那么递归调用插入函数继续往下找
     */
    public function insert($value,TreeNode $nowNode=null){
        if(empty($this->root)){
            $newNode = new TreeNode($value);
            $this->root = $newNode;

            return '设置根节点成功,值为'.$value;
        }


        if (empty($nowNode)) {
            $nowNode = $this->root;
        }

        if($value == $nowNode->getValue()){
            return '已经存在该节点,值为'.$value;
        }

        if ($value < $nowNode->getValue()) {
            $leftChild = $nowNode->getLeftChild();
            if(empty($leftChild)){
                $newNode = new TreeNode($value);
                $nowNode->setLeftChild($newNode);
                return '设置为左节点,父节点值:'.$nowNode->getValue();
            }else{
                return $this->insert($value,$leftChild);
            }
        }

        if ($value > $nowNode->getValue()) {
            $rightChild = $nowNode->getRightChild();
            if(empty($rightChild)){
                $newNode = new TreeNode($value);
                $nowNode->setRightChild($newNode);
                return '设置为右节点,父节点值:'.$nowNode->getValue();
            }else{
                return $this->insert($value,$rightChild);
            }
        }

        return '错误';
    }



    /**
     * 删除
     * 和查询类似,从根节点开始对比值,找到合适的点之后就把改点删除
     * 节点若无子节点,返回空
     * 节点若有一个子节点,那么该子节点代替原有节点作为父节点的左节点或右节点
     * 节点若有两个子节点,寻找后继子节点(节点右子节点一路寻找左子节点到最后一个(所有比被删除节点大的子节点中,最小的那个)),如果后继子节点有右子节点,那么把后继节点的右子节点顶替原有后继节点的位置
     */
    public function delete($value,TreeNode $nowNode){
        if(empty($nowNode)){
            return null;
        }elseif ($value < $nowNode->getValue()) {
            $leftChild = $this->delete($value,$nowNode->getLeftChild());
            $nowNode->setLeftChild($leftChild);
            return $nowNode;
        }elseif ($value > $nowNode->getValue()) {
            $rightChild = $this->delete($value,$nowNode->getRightChild());
            $nowNode->setRightChild($rightChild);
            return $nowNode;
        }elseif ($value == $nowNode->getValue()) {//找到要删除的节点了,那么寻找一个新的内容来替代原有节点,就等于删除了该节点
            //如果当前删除节点没有子节点,那么返回空作为上级的新节点
            if(empty($nowNode->getLeftChild())&&empty($nowNode->getRightChild())){
                return null;
            }elseif (empty($nowNode->getLeftChild())){
                //如果没有左子节点,那么返回右子节点作为上级的子节点(被删除节点由于缺乏和父级的关联,已经排除在树外了)
                return $nowNode->getRightChild();
            }elseif (empty($nowNode->getRightChild())){
                //如果没有右子节点,那么返回左子节点作为上级的子节点(被删除节点由于缺乏和父级的关联,已经排除在树外了)
                return $nowNode->getLeftChild();
            }else{
                //否则当前要删除的节点就是有左右子节点,寻找后继节点来替代被删除节点。同时,判断该后继节点是否有右子节点,如果有,那么返回给后继节点的父节点做父节点的左子节点
                $nowNode->setRightChild($this->lift($nowNode->getRightChild(),$nowNode));

                return $nowNode;
            }
        }

    }


    public function lift(TreeNode $node,$nodeToDelete){
        if($node->getLeftChild()){
            $leftChild = $this->lift($node->getLeftChild(),$nodeToDelete);
            $node->setLeftChild($leftChild);

            return $node;
        }else{
            //无左子节点,那么是后继节点,把后继节点的值替换掉被删除节点,完成替换,原节点已变成新节点
            $nodeToDelete->setValue = $node->getValue();
            //用后继节点的右子节点替代后继节点的父节点的左子节点,不管这个右子节点存在不存在
            return $node->getRightChild();
        }
    }

    /**
     * 查询
     * 从根节点开始对比值
     * 如果等于节点值,那么返回改节点
     * 如果小于节点值,那么拿到左节点,递归调用查询
     * 如果大于节点值,那么拿到右节点,递归调用查询
     * 如果遍历完都没有值,那么返回错误
     */
    public function search($value,$nowNode=null){
        if(empty($value)){
            return '查询失败,查询内容为空';
        }

        if(empty($nowNode)){
            if(empty($this->root)){
                return '查询失败,树为空';
            }

            $nowNode = $this->root;
        }

        if ($value == $nowNode->getValue()) {
            return $nowNode;
        } elseif ($value < $nowNode->getValue()) {
            if (!empty($nowNode->getLeftChild())) {
                return $this->search($value,$nowNode->getLeftChild());
            } else {
                return '没有找到';
            }
        } elseif ($value > $nowNode->getValue()) {
            if (!empty($nowNode->getRightChild())) {
                return $this->search($value,$nowNode->getRightChild());
            } else {
                return '没有找到';
            }
        } else {
            return '错误';
        }
    }

    //遍历树
    public function printTree($nowNode=null){
        if(empty($nowNode)){
            if(empty($this->root)){
                return '树为空';
            }

            $nowNode = $this->root;
        }

        echo $nowNode->getValue()."\n";
        if(!empty($nowNode->getLeftChild())){
            $this->printTree($nowNode->getLeftChild());
        }
        if(!empty($nowNode->getRightChild())){
            $this->printTree($nowNode->getRightChild());
        }
    }

}


$object = new Binar

 

 

设置根节点成功,值为3
设置为左节点,父节点值:3
设置为右节点,父节点值:3
设置为左节点,父节点值:2
设置为右节点,父节点值:4
设置为左节点,父节点值:9
已经存在该节点,值为3
设置为右节点,父节点值:5
查询值:2
,结果:object(TreeNode)#3 (3) {
  ["value":"TreeNode":private]=>
  int(2)
  ["leftChild":"TreeNode":private]=>
  object(TreeNode)#5 (3) {
    ["value":"TreeNode":private]=>
    int(1)
    ["leftChild":"TreeNode":private]=>
    NULL
    ["rightChild":"TreeNode":private]=>
    NULL
  }
  ["rightChild":"TreeNode":private]=>
  NULL
}

查询值:3
,结果:object(TreeNode)#2 (3) {
  ["value":"TreeNode":private]=>
  int(3)
  ["leftChild":"TreeNode":private]=>
  object(TreeNode)#3 (3) {
    ["value":"TreeNode":private]=>
    int(2)
    ["leftChild":"TreeNode":private]=>
    object(TreeNode)#5 (3) {
      ["value":"TreeNode":private]=>
      int(1)
      ["leftChild":"TreeNode":private]=>
      NULL
      ["rightChild":"TreeNode":private]=>
      NULL
    }
    ["rightChild":"TreeNode":private]=>
    NULL
  }
  ["rightChild":"TreeNode":private]=>
  object(TreeNode)#4 (3) {
    ["value":"TreeNode":private]=>
    int(4)
    ["leftChild":"TreeNode":private]=>
    NULL
    ["rightChild":"TreeNode":private]=>
    object(TreeNode)#6 (3) {
      ["value":"TreeNode":private]=>
      int(9)
      ["leftChild":"TreeNode":private]=>
      object(TreeNode)#7 (3) {
        ["value":"TreeNode":private]=>
        int(5)
        ["leftChild":"TreeNode":private]=>
        NULL
        ["rightChild":"TreeNode":private]=>
        object(TreeNode)#8 (3) {
          ["value":"TreeNode":private]=>
          int(6)
          ["leftChild":"TreeNode":private]=>
          NULL
          ["rightChild":"TreeNode":private]=>
          NULL
        }
      }
      ["rightChild":"TreeNode":private]=>
      NULL
    }
  }
}

查询值:9
,结果:object(TreeNode)#6 (3) {
  ["value":"TreeNode":private]=>
  int(9)
  ["leftChild":"TreeNode":private]=>
  object(TreeNode)#7 (3) {
    ["value":"TreeNode":private]=>
    int(5)
    ["leftChild":"TreeNode":private]=>
    NULL
    ["rightChild":"TreeNode":private]=>
    object(TreeNode)#8 (3) {
      ["value":"TreeNode":private]=>
      int(6)
      ["leftChild":"TreeNode":private]=>
      NULL
      ["rightChild":"TreeNode":private]=>
      NULL
    }
  }
  ["rightChild":"TreeNode":private]=>
  NULL
}

查询值:4
,结果:object(TreeNode)#4 (3) {
  ["value":"TreeNode":private]=>
  int(4)
  ["leftChild":"TreeNode":private]=>
  NULL
  ["rightChild":"TreeNode":private]=>
  object(TreeNode)#6 (3) {
    ["value":"TreeNode":private]=>
    int(9)
    ["leftChild":"TreeNode":private]=>
    object(TreeNode)#7 (3) {
      ["value":"TreeNode":private]=>
      int(5)
      ["leftChild":"TreeNode":private]=>
      NULL
      ["rightChild":"TreeNode":private]=>
      object(TreeNode)#8 (3) {
        ["value":"TreeNode":private]=>
        int(6)
        ["leftChild":"TreeNode":private]=>
        NULL
        ["rightChild":"TreeNode":private]=>
        NULL
      }
    }
    ["rightChild":"TreeNode":private]=>
    NULL
  }
}

删除前object(BinaryTree)#1 (1) {
  ["root"]=>
  object(TreeNode)#2 (3) {
    ["value":"TreeNode":private]=>
    int(3)
    ["leftChild":"TreeNode":private]=>
    object(TreeNode)#3 (3) {
      ["value":"TreeNode":private]=>
      int(2)
      ["leftChild":"TreeNode":private]=>
      object(TreeNode)#5 (3) {
        ["value":"TreeNode":private]=>
        int(1)
        ["leftChild":"TreeNode":private]=>
        NULL
        ["rightChild":"TreeNode":private]=>
        NULL
      }
      ["rightChild":"TreeNode":private]=>
      NULL
    }
    ["rightChild":"TreeNode":private]=>
    object(TreeNode)#4 (3) {
      ["value":"TreeNode":private]=>
      int(4)
      ["leftChild":"TreeNode":private]=>
      NULL
      ["rightChild":"TreeNode":private]=>
      object(TreeNode)#6 (3) {
        ["value":"TreeNode":private]=>
        int(9)
        ["leftChild":"TreeNode":private]=>
        object(TreeNode)#7 (3) {
          ["value":"TreeNode":private]=>
          int(5)
          ["leftChild":"TreeNode":private]=>
          NULL
          ["rightChild":"TreeNode":private]=>
          object(TreeNode)#8 (3) {
            ["value":"TreeNode":private]=>
            int(6)
            ["leftChild":"TreeNode":private]=>
            NULL
            ["rightChild":"TreeNode":private]=>
            NULL
          }
        }
        ["rightChild":"TreeNode":private]=>
        NULL
      }
    }
  }
}

删除后object(BinaryTree)#1 (1) {
  ["root"]=>
  object(TreeNode)#2 (3) {
    ["value":"TreeNode":private]=>
    int(3)
    ["leftChild":"TreeNode":private]=>
    object(TreeNode)#3 (3) {
      ["value":"TreeNode":private]=>
      int(2)
      ["leftChild":"TreeNode":private]=>
      object(TreeNode)#5 (3) {
        ["value":"TreeNode":private]=>
        int(1)
        ["leftChild":"TreeNode":private]=>
        NULL
        ["rightChild":"TreeNode":private]=>
        NULL
      }
      ["rightChild":"TreeNode":private]=>
      NULL
    }
    ["rightChild":"TreeNode":private]=>
    object(TreeNode)#6 (3) {
      ["value":"TreeNode":private]=>
      int(9)
      ["leftChild":"TreeNode":private]=>
      object(TreeNode)#7 (3) {
        ["value":"TreeNode":private]=>
        int(5)
        ["leftChild":"TreeNode":private]=>
        NULL
        ["rightChild":"TreeNode":private]=>
        object(TreeNode)#8 (3) {
          ["value":"TreeNode":private]=>
          int(6)
          ["leftChild":"TreeNode":private]=>
          NULL
          ["rightChild":"TreeNode":private]=>
          NULL
        }
      }
      ["rightChild":"TreeNode":private]=>
      NULL
    }
  }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值