• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

44-数据结构PHP实现-二分搜索树的结点删除

php 搞代码 3年前 (2022-03-01) 16次浏览 已收录 0个评论

1. 删除逻辑

  • 删除的结点不存在左儿子:

  • 删除的结点不存在右儿子:

  • 删除的结点存在左儿子和右儿子:

删除的结点的右边所有值都会比该结点小,所以只有在其中拿出最大的一个值替换成该节点即可

2. 代码

<?php
/**
 * content: 二叉树的二分搜寻树的实现
 * auth: yujiaming
 * create: 2020-10-25
 */
namespace TreeBundle;

use ArrayBundle\BaseArray;
use QueueBundle\BaseQueue;
use StackBundle\BaseStack;

class BaseBinaryTree
{

    /**
     * 删除某个结点
     * @param $value
     */
    public function deleteNode($value)
    {
        $node = $this->rootNode;
        $parentNode = null;

        while (!is_null($node)) {
            if (bccomp($node->getValue(), $value) > 0) {
                $parentNode = $node;
                $node = $node->getLeftChild();
            } elseif (bccomp($node->getValue(), $value) < 0) {
                $parentNode = $node;
                $node = $node->getRightChild();
            } else {
                // 如果不存在右儿子,则左儿子间接挂到父节点上面即可
                if (is_null($node->getRightChild())) {
                    // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子
                    if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) {
                        $parentNode->setLeftChild($node->getLeftChild());
                    } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) {
                        $parentNode->setRightChild($node->getLeftChild());
                    }
                    return;
                }

                // 如果不存在左儿子,则右儿子间接挂到父节点上面即可
                if (is_null($node->getLeftChild())) {
                    // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子
                    if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) {
                        $parentNode->setLeftChild($node->getRightChild());
                    } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) {
                        $parentNode->setRightChild($node->getRightChild());
                    }
                    return;
                }

                // 如果左儿子和右儿子都存在,则获取右儿子里最小的结点来代替该结点

                // 定义以后结点左儿子的最大结点的父节点
                $leftMaxNodeParent = $node;
                // 定义以后结点左儿子的最大结点
                $leftMaxNode = $leftMaxNodeParent->getLeftChild();
                // 遍历
                while (!is_null($leftMaxNode) && !is_null($leftMaxNode->getRightChild())) {
                    $leftMaxNodeParent = $leftMaxNode;
                    $leftMaxNode = $leftMaxNode->getRightChild();
                }
                // 将以后结点左儿子的最大结点的父节点的右儿子设置为null
                $leftMaxNodeParent->setRightChild(null);
                // 将以后结点左儿子的最大结点的左儿子和右儿子设置为该结点的左儿子和右儿子
                $leftMaxNode->setLeftChild($node->getLeftChild());
                $leftMaxNode->setRightChild($node->getRightChild());

                // 将新节点接到父节点下,这里要判断是父节点的左儿子还是右儿子
                if (!is_null($parentNode->getLeftChild()) && bccomp($parentNode->getLeftChild()->getValue(), $node->getValue()) == 0) {
                    $parentNode->setLeftChild($leftMaxNode);
                } elseif (!is_null($parentNode->getRightChild()) && bccomp($parentNode->getRightChild()->getValue(), $node->getValue()) == 0) {
                    $parentNode->setRightChild($leftMaxNode);
                }
                return;
            }
        }
    }
    
    // ...其余代码

}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:44-数据结构PHP实现-二分搜索树的结点删除
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址