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

  • 相关阅读:
    On the fly test
    Spec Explorer 工具学习
    C# Static修饰符的作用
    [转]C#静态方法与非静态方法的比较
    如何获取网站服务器运行状态
    C#快速整理代码格式
    UI auto程序结构组织方式
    TestClass必须是public的
    VS2012如何显示行号
    Error: member names cannot be the same as their enclosing type
  • 原文地址:https://www.cnblogs.com/rxbook/p/10419365.html
Copyright © 2011-2022 走看看