如何修改此树节点插入逻辑以生成平衡二叉树?

时间:2016-07-25 18:38:04

标签: php binary-tree

我是树木编码的新手。

给出以下输入数组 -

array(10,7,13,5,6,8,11,15,14,4,3,16)

我想通过从第一个元素开始逐个插入这些值来准备一个平衡的二叉树(应插入一个节点的左子节点,然后插入右子节点,然后检查下一个节点以插入它左边在插入更高级别之前,所有插入都应首先发生在一个级别上。结果应该如下所示 -

enter image description here

这是我现在的代码(从我发现的{BST代码here中修改了一下)

<?php


class Node
{

    public $left;
    public $right;
    public $data;

    public function __construct($data)
    {
        $this->data = $data;
        $this->right = NULL;
        $this->left = NULL;
    }

} //End class Node

class BTree
{

    public $root;

    public function __construct()
    {
        $this->root = NULL;
    }

    /* Insert the first node to the BST*/
    public function insert($data)
    {

        $node = new Node($data);

        if($this->root === NULL)
                $this->root = $node;
        else 
            $this->insertNode($this->root,$node);

    }

    /* Insert node starting from root */
    public function insertNode(&$root,$node)
    {
            if($root === NULL)
            {//root is not occupied, set root as the node
                $root = $node;
            }
            else
            {   
                if($root->left && $root->left->data===null) 
                {
                    $root->left==$node;
                }
                else 
                {
                    if($root->right && $root->right->data===null) //Not using else to avoid duplicate values
                    {
                        $root->right==$node;
                    }
                    else
                    {
                        $this->insertNode($root->left,$node); //Search for place in the right side to insert        
                    }
                }
            }       
    }

    /* Get an array and insert all items in it to the tree in the array order */
    public function multiInsert($array)
    {

        foreach($array as $data)
            $this->insert($data);
    }


    /*
    Draw the tree from left to right
    Line with same color are in same level of the tree
    */
    public function draw($node = 'root', $depth = 0)
    {

        if($node == 'root') $node = $this->root; /* If node not selected the default is the tree root */

        if ($node === null) return;

        return
            $this->draw($node->right, $depth + 1).str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $depth).
            "<span style='color:".(($depth%2 == 0)? 'red' : 'blue')."'>".$node->data."</span><br>".
            $this->draw($node->left, $depth + 1);
    }

} //End class BTree


/* ########### EXAMPLE ########### */
echo '<h1>Binary Tree</h1>';
$tree = new BTree();
$tree->multiInsert(array(10,7,13,5,6,8,11,15,14,4,3,16));
echo'<br><br>';
echo $tree->draw();

?>

这导致只有左子节点的树,如以下输出所示 -

enter image description here

1 个答案:

答案 0 :(得分:2)

此:

if($root->left && $root->left->data===null) 
   ^^^^^^^^^^^

您将节点初始化为null,因此$root->left为空,将评估为false,向您发送else路径。 $root->right也为空,因此您最终会转到insertNode($root->left),最后会得到一个空节点,并无条件地将其分配给left

你应该这样做

if (is_null($root->left)) {
    $root->left = $node
} else if (is_null($root->right)) {
    $root->right = $node;
} else (
    $this->insertNode(...);
}