PHP实现二叉树的深度优先遍历(前序、中序、后序)和广度优先遍历(层次)
前言:
深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历。具体说明如下:
- 前序遍历:根节点->左子树->右子树
- 中序遍历:左子树->根节点->右子树
- 后序遍历:左子树->右子树->根节点
广度优先遍历:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
例如对于一下这棵树:

深度优先遍历:
- 前序遍历:10 8 7 9 12 11 13
- 中序遍历:7 8 9 10 11 12 13
- 后序遍历:7 9 8 11 13 12 10
广度优先遍历:
- 层次遍历:10 8 12 7 9 11 13
二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。
代码示例:
<?php
header("Content-type: text/html; charset=utf-8");
class Node
{
public $value;
public $left;
public $right; public function __construct($value)
{
$this->value = $value;
}
} class Tree
{
/**
* 先序遍历(递归方法)
*/
public function recursion_preorder($root)
{
static $res = array();
if (!is_null($root))
{
$function = __FUNCTION__;
$res[] = $root->value;
$this->$function($root->left);
$this->$function($root->right);
}
return $res;
} /**
* 中序遍历(递归方法)
*/
public function recursion_midorder($root)
{
static $res = array();
if(!is_null($root))
{
$function = __FUNCTION__;
$this->$function($root->left);
$res[] = $root->value;
$this->$function($root->right);
}
return $res;
} /**
* 后序遍历(递归方法)
*/
public function recursion_postorder($root)
{
static $res = array();
if (!is_null($root))
{
$function = __FUNCTION__;
$this->$function($root->left);
$this->$function($root->right);
$res[] = $root->value;
}
return $res;
} /**
* 先序遍历(非递归)
*/
public function preorder($node)
{
$res = array();
$stack = new splstack();
while(!is_null($node) || !$stack->isEmpty())
{
while(!is_null($node))//节点不为空就入栈
{
$stack->push($node);
$res[] = $node->value;
$node = $node->left;
}
$node = $stack->pop();
$node = $node->right;
}
return $res;
} /**
* 中序遍历(非递归)
*/
public function midorder($node)
{
$res = array();
$stack = new splstack();
while(!is_null($node) || !$stack->isEmpty())
{
while(!is_null($node))
{
$stack->push($node);
$node = $node->left;
}
$node = $stack->pop();
$res[] = $node->value;
$node = $node->right;
}
return $res;
} /**
* 后序遍历(非递归)
*/
public function postorder($node)
{
$stack = new splstack();
$outstack = new splstack(); $stack->push($node);
while(!$stack->isEmpty())
{
$center_node = $stack->pop();
$outstack->push($center_node);//最先压入根节点,最后输出
if(!is_null($center_node->left))
{
$stack->push($center_node->left);
}
if(!is_null($center_node->right))
{
$stack->push($center_node->right);
}
} $res = array();
while(!$outstack->isEmpty())
{
$node = $outstack->pop();
$res[] = $node->value;
}
return $res;
} /**
* 广度优先遍历(层次遍历、非递归)
*/
public function level_order($node)
{
$res = array();
$queue = new splqueue();
$queue->enqueue($node);
while(!$queue->isEmpty())
{
$node = $queue->dequeue();
$res[] = $node->value;
if(!is_null($node->left))
{
$queue->enqueue($node->left);
}
if(!is_null($node->right))
{
$queue->enqueue($node->right);
}
}
return $res;
}
} $a = new Node(10);
$b = new Node(8);
$c = new Node(12);
$d = new Node(7);
$e = new Node(9);
$f = new Node(11);
$g = new Node(13); $a->left = $b;
$a->right = $c;
$b->left = $d;
$b->right = $e;
$c->left = $f;
$c->right = $g; $tree = new Tree();
$res = $tree->recursion_preorder($a);
echo "先序遍历结果(递归):" . implode('-', $res) . "<br/>"; $res = $tree->preorder($a);
echo "先序遍历结果(非递归):" . implode('-', $res) . "<br/>"; $res = $tree->recursion_midorder($a);
echo "中序遍历结果(递归):" . implode('-', $res) . "<br/>"; $res = $tree->midorder($a);
echo "中序遍历结果(非递归):" . implode('-', $res) . "<br/>"; $res = $tree->recursion_postorder($a);
echo "后序遍历结果(递归):" . implode('-', $res) . "<br/>"; $res = $tree->postorder($a);
echo "后序遍历结果(非递归):" . implode('-', $res) . "<br/>"; $res = $tree->level_order($a);
echo "层次遍历结果(非递归):" . implode('-', $res) . "<br/>";
PHP实现二叉树的深度优先遍历(前序、中序、后序)和广度优先遍历(层次)的更多相关文章
- 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序
接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...
- 二叉树 遍历 先序 中序 后序 深度 广度 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- LeetCode:二叉树的前、中、后序遍历
描述: ------------------------------------------------------- 前序遍历: Given a binary tree, return the pr ...
- 【数据结构】二叉树的遍历(前、中、后序及层次遍历)及leetcode107题python实现
文章目录 二叉树及遍历 二叉树概念 二叉树的遍历及python实现 二叉树的遍历 python实现 leetcode107题python实现 题目描述 python实现 二叉树及遍历 二叉树概念 二叉 ...
- SDUT OJ 数据结构实验之二叉树八:(中序后序)求二叉树的深度
数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...
- SDUT-2804_数据结构实验之二叉树八:(中序后序)求二叉树的深度
数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知一颗二叉树的中序 ...
- 前序+中序->后序 中序+后序->前序
前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...
- 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树
已知 中序&后序 建立二叉树: SDUT 1489 Description 已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input 输入数据有多组,第一行是一个整数t (t& ...
- 【C&数据结构】---关于链表结构的前序插入和后序插入
刷LeetCode题目,需要用到链表的知识,忽然发现自己对于链表的插入已经忘得差不多了,以前总觉得理解了记住了,但是发现真的好记性不如烂笔头,每一次得学习没有总结输出,基本等于没有学习.连复盘得机会都 ...
- 【11】-java递归和非递归二叉树前序中序后序遍历
二叉树的遍历 对于二叉树来讲最主要.最基本的运算是遍历. 遍历二叉树 是指以一定的次序访问二叉树中的每个结点.所谓 访问结点 是指对结点进行各种操作的简称.例如,查询结点数据域的内容,或输出它的值,或 ...
随机推荐
- PostgreSQL&PostGIS完全安装
检查PostGIS.PostgreSQL.GEOS.GDAL.PROJ等各软件的版本依赖关系 http://trac.osgeo.org/postgis/wiki/UsersWikiPostgreSQ ...
- python中bottle模块的使用
1.简介 2.示例 2.1一个简单的bottle接口 # -*- coding: utf-8 -*- from bottle import route, request, run import jso ...
- axios全局设置url公共请求头
需求由来:公司项目外链到别公司项目或者网页(通俗的说就是通过别的随意网页跳转至你项目网页),这时公司项目就要区分是从哪个公司或者哪个网页跳转过来的,从而进行不同的接口请求(公司所有接口都要带上请求头) ...
- 一、JAVA内存区域与内存溢出异常
在虚拟机自动内存管理机制的帮助下,不在需要为每一个操作区写相对应的delete/free代码来进行内存释放.进而不容易出现内存泄露和内存溢出的问题,由虚拟机管理内存,貌似这一切看起来很好.也正是因为j ...
- Qt一步一步实现插件通信(附源码)
前一章已经实现了主程序调用加载插件功能,这一章描述主程序和插件间通信功能 说道Qt的通信必须要了解信号和槽的机制原理,这里不做论述,不清楚的同学去看看信号和槽机制 不废话直接上步骤,在上一章的基础 ...
- PL/SQL Developer安装教程
1.下载:http://pan.baidu.com/s/1qYtvy1I密码:451g instantclient官方下载链接:http://www.oracle.com/technetwork/to ...
- re随机模块应用-生成验证码(无图片)
方法一,通过choice方式生成验证码 此方法生成每次调用crate_code()会生成三个随机数,然后再三个随机数中选择一个,资源调用相对多些 import random def v_code(co ...
- liunx 随笔集
Linux 安装时 Customize Now(自定义选包)选包如下 base system -> base , compatibility libraries,debugging Tool ...
- react+dva+antd/antd-mobile
github仓库pc: https://github.com/llcMite/react-dva-antd.git github仓库mobile:https://github.com/llcMite/ ...
- [POJ3416]Crossing
Problem 给你n个点,m个询问,每个询问有x, y 问以(x,y)为原点建立的平面直角坐标系分割的第一象限和第三象限的点数和减去第二象限和第四象限的点数和 Solution 用2个树状数组维护一 ...