zoukankan      html  css  js  c++  java
  • php循环方法实现先序、中序、后序遍历二叉树

    二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。

    <?php
    
    namespace appdata_structure	ree;
    
    /**
     * php循环方法实现前序、中序、后序遍历二叉树
     * 二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)
     * https://www.cnblogs.com/rxbook/p/10419365.html
     */
    
    class BinaryTree2
    {
        public $value;
        public $left;
        public $right;
    }
    
    /**
     * 前序遍历
     * 根节点 ---> 左子树 ---> 右子树
     */
    function preorder($root)
    {
        //PE($root);
        $stack = array();
        array_push($stack, $root); //将$root(树对象)放入数组$stack中
        while (!empty($stack)) {
            //删除数组中的最后一个元素,并返回数组的最后一个值,此处$tree返回的就是完整的$root树对象,此时$stack为空
            $tree = array_pop($stack);
            //PE($tree);
            //PE($stack);
            echo $tree->value . ' ';//先输出根节点
    
            //由于在循环的过程中,每次array_pop都是删除最后一个元素并返回,因此要先将右子树压进去
            if ($tree->right != null) {
                array_push($stack, $tree->right);//压入右子树
            }
    
            //再将左树压进去,这样能保证左树处于最后一个元素,下次循环就会先处理左子树
            if ($tree->left != null) {
                array_push($stack, $tree->left); //压入左子树
            }
            //PE($stack);
        }
    }
    
    /**
     * 中序遍历
     * 左子树---> 根节点 ---> 右子树
     */
    function inorder($root)
    {
        $stack = array();
        //最开始,让$tree=最原始的树
        $tree = $root;
        while (!empty($stack) || $tree != null) {
            while ($tree != null) {
                //将整个树存入$stack数组中,然后让树变成左子树,依次循环,把全部的左子树存入$stack数组
                array_push($stack, $tree);
                //直到最后一个左子树,已经没有了left节点,此时$tree为空。相当于把所有层次的树全都压入了$stack数组中
                $tree = $tree->left;
            }
            //P($stack);
    
            //从$stack的尾部依次弹出元素并输出,结果就是左子树从最底部到最顶部的值
            $tree = array_pop($stack);
            echo $tree->value . " ";
    
            //此时,将 右子树赋值给 $tree。在没有到达主树之前,所有的右子树都是空,但是$stack不为空。
            //也就导致下次内循环的 while($tree != null)不会执行,一直到左子树输出完毕,到达主树(此时$stack为空)。
            //由于主树的右子树不为空,从而会执行 while($tree != null),然后会再次将右子树的左子树依次输出,直到输出完最后一个右子树(已经没有了左子树)
            $tree = $tree->right;
            //PE($tree);
        }
    }
    
    /**
     * 后序遍历
     * 左子树 ---> 右子树 ---> 根节点
     */
    function tailorder($root)
    {
        $stack = array();
        $outstack = array();
        array_push($stack, $root);
        while (!empty($stack)) {
            $tree = array_pop($stack);
            array_push($outstack, $tree);//最先压入根节点,最后输出
            if ($tree->left != null) {
                array_push($stack, $tree->left);
            }
            if ($tree->right != null) {
                array_push($stack, $tree->right);
            }
        }
    
        while (!empty($outstack)) {
            $tree = array_pop($outstack);
            echo $tree->value . ' ';
        }
    }
    
    //测试
    $a = new BinaryTree2();
    $b = new BinaryTree2();
    $c = new BinaryTree2();
    $d = new BinaryTree2();
    $e = new BinaryTree2();
    $f = new BinaryTree2();
    
    $a->value = 'A';
    $b->value = 'B';
    $c->value = 'C';
    $d->value = 'D';
    $e->value = 'E';
    $f->value = 'F';
    
    $a->left = $b;
    $a->right = $c;
    $b->left = $d;
    $c->left = $e;
    $c->right = $f;
    
    echo "php循环方法实现前序、中序、后序遍历二叉树: 
    ";
    echo "前序遍历:";
    preorder($a); //A B D C E F
    echo "
    ";
    
    echo "中序遍历:";
    inorder($a);//D B A E C F
    echo "
    ";
    
    echo "后序遍历:";
    tailorder($a);//D B E F C A
    echo "
    ";

     结果:

    A B D C E F


    D B A E C F


    D B E F C A

  • 相关阅读:
    背水一战 Windows 10 (26)
    背水一战 Windows 10 (25)
    背水一战 Windows 10 (24)
    背水一战 Windows 10 (23)
    背水一战 Windows 10 (22)
    背水一战 Windows 10 (21)
    背水一战 Windows 10 (20)
    背水一战 Windows 10 (19)
    背水一战 Windows 10 (18)
    背水一战 Windows 10 (17)
  • 原文地址:https://www.cnblogs.com/rxbook/p/10419365.html
Copyright © 2011-2022 走看看