反转二叉树是这个圈子里一个著名的梗,所以我把这个操作单独拿出来。

所谓反转二叉树,就是把左右子树对换。我将用两种方式来实现,一种是递归的,另一种是非递归的。

static function invertBinaryTree1($tree){
    if(!($tree instanceof Node_tree)){
        return false;
    }

    $temp = $tree->leftNode;
    $tree->leftNode = $tree->rightNode;
    $tree->rightNode = $temp;
    self::invertBinaryTree($tree->leftNode);
    self::invertBinaryTree($tree->rightNode);
    return true;
}

上面是递归实现反转二叉树,我们反转的顺序是从上到下,不过通过调整代码顺序,我们可以轻松实现从下到上反转二叉树。

static function invertBinaryTree2($tree){
    if(!($tree instanceof Node_tree)){
        return false;
    }
    $queue = [];
    array_push($queue,$tree);
    while(!empty($queue)){
        $node = array_shift($queue);
        if($node->leftNode){
            array_push($queue,$node->leftNode);
        }
        if($node->rightNode){
            array_push($queue,$node->rightNode);
        }

        $temp = $node->leftNode;
        $node->leftNode = $node->rightNode;
        $node->rightNode = $temp;
    }
    return true;
}

上面是非递归实现反转二叉树,可以看到和层序遍历类似,我使用了一个队结构。上面的实现反转是从上到下进行的。

到现在我们的代码清单如下:

class Node_tree{
    public $leftNode = NULL;
    public $rightNode = NULL;
    public $parentNode = NULL;
    public $data;
    function __construct($value=NULL){
        $this->update($value);
    }

    function update($newValue){
        $this->data = $newValue;
    }

    protected function _formatNode($value){
        if(!($value instanceof Node_tree)){
            $value = new Node_tree($value);
        }
        $value->parentNode = $this;
        return $value;
    }

    function setLeft($value){
        $node = $this->_formatNode($value);
        $this->leftNode = $node;
    }

    function setRight($value){
        $value = $this->_formatNode($value);
        $this->rightNode = $value;
    }

    // 树的深度
    static function depth($tree){
        $leftDepth = 0;
        $rightDepth = 0;
        if($tree->leftNode){
            $leftDepth = self::depth($tree->leftNode);
        }
        if($tree->rightNode){
            $rightDepth = self::depth($tree->rightNode);
        }
        return max($leftDepth,$rightDepth) + 1;
    }

    // 节点的层次
    function level(){
        $count = 1;
        $parentNode = $this->parentNode;
        while($parentNode){
            $parentNode = $parentNode->parentNode;
            $count++;
        }
        return $count;
    }

    // 节点数量
    static function length($tree){
        $leftTreeLength = 0;
        $rightTreeLength = 0;
        if($tree->leftNode){
            $leftTreeLength = self::length($tree->leftNode);
        }
        if($tree->rightNode){
            $rightTreeLength = self::length($tree->rightNode);
        }
        return $leftTreeLength + $rightTreeLength + 1;
    }

    static function preOrderTraversal($tree,$fn){
        if(!($tree instanceof Node_tree)){
            return false;
        }
        if(is_callable($fn,true)){
            $fn($tree->data);
        }
        self::preOrderTraversal($tree->leftNode,$fn);
        self::preOrderTraversal($tree->rightNode,$fn);
    }

    static function inOrderTraversal($tree,$fn){
        if(!($tree instanceof Node_tree)){
            return false;
        }

        self::inOrderTraversal($tree->leftNode,$fn);
        if(is_callable($fn,true)){
            $fn($tree->data);
        }
        self::inOrderTraversal($tree->rightNode,$fn);
    }

    static function postOrderTraversal($tree,$fn){
        if(!($tree instanceof Node_tree)){
            return false;
        }

        self::postOrderTraversal($tree->leftNode,$fn);
        self::postOrderTraversal($tree->rightNode,$fn);
        if(is_callable($fn,true)){
            $fn($tree->data);
        }
    }

    static function levelOrderTraversal($tree,$fn){
        if(!($tree instanceof Node_tree)){
            return false;
        }
        $queue = [];
        array_push($queue,$tree);
        while(!empty($queue)){
            $node = array_shift($queue);
            if(is_callable($fn,true)){
                $fn($node->data);
            }
            if($node->leftNode){
                array_push($queue,$node->leftNode);
            }
            if($node->rightNode){
                array_push($queue,$node->rightNode);
            }
        }
        return true;
    }

    static function invertBinaryTree1($tree){
        if(!($tree instanceof Node_tree)){
            return false;
        }

        $temp = $tree->leftNode;
        $tree->leftNode = $tree->rightNode;
        $tree->rightNode = $temp;
        self::invertBinaryTree($tree->leftNode);
        self::invertBinaryTree($tree->rightNode);
        return true;
    }

    static function invertBinaryTree2($tree){
        if(!($tree instanceof Node_tree)){
            return false;
        }
        $queue = [];
        array_push($queue,$tree);
        while(!empty($queue)){
            $node = array_shift($queue);
            if($node->leftNode){
                array_push($queue,$node->leftNode);
            }
            if($node->rightNode){
                array_push($queue,$node->rightNode);
            }

            $temp = $node->leftNode;
            $node->leftNode = $node->rightNode;
            $node->rightNode = $temp;
        }
        return true;
    }


}

results matching ""

    No results matching ""