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

<?php

namespace app\data_structure\tree;

/**
* 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循环方法实现前序、中序、后序遍历二叉树: \n";
echo "前序遍历:";
preorder($a); //A B D C E F
echo "\n"; echo "中序遍历:";
inorder($a);//D B A E C F
echo "\n"; echo "后序遍历:";
tailorder($a);//D B E F C A
echo "\n";

结果:

A B D C E F


D B A E C F


D B E F C A

php循环方法实现先序、中序、后序遍历二叉树的更多相关文章

  1. DS Tree 已知先序、中序 => 建树 => 求后序

    参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...

  2. 已知树的前序、中序,求后序的java实现&已知树的后序、中序,求前序的java实现

    public class Order { int findPosInInOrder(String str,String in,int position){ char c = str.charAt(po ...

  3. TZOJ 3209 后序遍历(已知中序前序求后序)

    描述 在数据结构中,遍历是二叉树最重要的操作之一.所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 这里给出三种遍历算法. 1.中序遍历的递归算法定义:  ...

  4. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

  5. [Java]算术表达式求值之一(中序表达式转后序表达式方案)

    第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...

  6. LeetCode:二叉树的前、中、后序遍历

    描述: ------------------------------------------------------- 前序遍历: Given a binary tree, return the pr ...

  7. 【数据结构】二叉树的遍历(前、中、后序及层次遍历)及leetcode107题python实现

    文章目录 二叉树及遍历 二叉树概念 二叉树的遍历及python实现 二叉树的遍历 python实现 leetcode107题python实现 题目描述 python实现 二叉树及遍历 二叉树概念 二叉 ...

  8. 分别求二叉树前、中、后序的第k个节点

    一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 ; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' ...

  9. HDU 1710 (二叉树的前序和中序,求后序)

    题目链接 题目大意: 输入二叉树的前序.中序遍历,请输出它的后序遍历 #include <stdio.h> #include <string.h> ; // 长度为n s1 前 ...

  10. HDU 1710Binary Tree Traversals(已知前序中序,求后序的二叉树遍历)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710 解题思路:可以由先序和中序的性质得到 : 先序的第一个借点肯定是当前子树的根结点, 那么在 中序 ...

随机推荐

  1. svn st 状态详解

    svn st status (stat, st): 显示工作副本中目录与文件的状态.用法: status [PATH...]  未指定参数时,只显示本地修改的条目(没有网络访问).  使用 -q 时, ...

  2. springboot之thymeleaf学习

    这是springboot的view层不建议使用jsp,而是thymeleaf,虽然我也不知道为什么,但是后来可能会明白一些.学springBoot也遇到很多bug,导致脱累了进度.有点类似于jsp,但 ...

  3. 书写 sql 中关于 update 多表联合更新的方法

    SQL Update多表联合更新的方法(1) sqlite 多表更新方法//----------------------------------update t1 set col1=t2.col1fr ...

  4. 栈的C语言实现

    在C++中,可以直接使用std::stack C语言实现如下: stack.c /** * @file stack.c * @brief 栈,顺序存储. * * * */ #include <s ...

  5. ABP之展现层(导航菜单)

    基本的增删改查已经粗糙的结束了,接下来就是要方便的展示了,也就是导航菜单.在Abp中已经对导航栏的设置进行了相应的封装(Abp.Application.Navigation),可以方便我们快速的将自己 ...

  6. Android最全开发资源(申明:来源于网络)

    Android最全开发资源(申明:来源于网络) 地址:http://www.jianshu.com/p/0c36302e0ed0?ref=myread

  7. EHCI规范(转)

    https://blog.csdn.net/qiurihuanghua/article/details/6411640 1. EHCI 1.0规范介绍 EHCI规范为USB 2.0规范定义了一个Hos ...

  8. [filesystem][archlinux][disk encryption][btrfs] btrfs

    fork from here http://www.cnblogs.com/hugetong/p/6914248.html boot分区,MBR加密:https://wiki.archlinux.or ...

  9. NOIP 2018 day1 题解

    今年noip的题和去年绝对是比较坑的题了,但是打好的话就算是普通水准也能350分以上吧. t1: 很显然这是一个简单的dp即可. #include<iostream> #include&l ...

  10. 为QtCreator项目模板添加自动中文支持

    每用QtCreator创建一个Qt项目时都要为它添加中文支持,比如qt4: 就要在main.cpp里添加 QTextCodec* codec = QTextCodec::codecForName(&q ...