php 二叉树遍历算法与例子
二叉树算法在小编大学时学数据结构时会学到的一个算法了,这个可以在搜索与排序中提高50%的搜索性能了,下面我们来看一些关于php 二叉树遍历算法与例子吧。
二叉树遍历,是值从根节点出发,按照某种次序依次访问二叉树中的所有节点,使得每个节点被访问一次且仅被访问依
图是百度搜的。。。谢谢提供图的英雄。。
前序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则先遍历左树,再遍历右树,遍历顺序为ABCDEGF。
中序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从根节点开始,中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树,遍历顺序为CBEGDFA。
后序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从左到右先叶子后节点的访问遍历访问左右子树,最后是访问根节点。访问顺序为CGEFDBA。
层序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从树的第一层,也就是根节点开始访问,从上而下逐层遍历,在同一层中,按照从左到右的顺序对节点逐个访问。访问顺序为ABCDEFG。
现在,我们用PHP代码,来遍历二叉树结构。二叉树是放一个大数组,每一个节点都有三个字段,data表示这个节点的值,lChild表示这个节点的左边子节点,rChild表示这个节点的右边子节点。二叉树的结构我们用上面那张图。
二叉树结构代码如下:
<?php //二叉树 $arr = array( 'data' => 'A', 'lChild' => array( 'data' => 'B', 'lChild' => array( 'data' => 'C', 'lChild' => array() , 'rChild' => array() , ) , 'rChild' => array( 'data' => 'D', 'lChild' => array( 'data' => 'E', 'lChild' => array() , 'rChild' => array( 'data' => 'G', 'lChild' => array() , 'rChild' => array() , ) , ) , 'rChild' => array( 'data' => 'F', 'lChild' => array() , 'rChild' => array() , ) , ) , ) , 'rChild' => array() , );
遍历算法一:前序遍历二叉树
<?php //前序遍历二叉树算法 echo '前序遍历二叉树算法:'; PreOrderTraverse($arr); echo '<Br>'; function PreOrderTraverse($node) { if (empty($node)) { return; } //输出值 print_r($node['data']); //左节点 PreOrderTraverse($node['lChild']); //右节点 PreOrderTraverse($node['rChild']); }
遍历算法二:中序遍历二叉树
<?php //中序遍历二叉树算法 echo '中序遍历二叉树算法:'; inOrderTraverse($arr); echo '<Br>'; function inOrderTraverse($node) { if (empty($node)) { return; } //左节点 inOrderTraverse($node['lChild']); //输出值 print_r($node['data']); //右节点 inOrderTraverse($node['rChild']); }
遍历算法三:后序遍历二叉树
<?php //后序遍历二叉树算法 echo '后序遍历二叉树算法:'; postOrderTraverse($arr); echo '<Br>'; function postOrderTraverse($node) { if (empty($node)) { return; } //左节点 postOrderTraverse($node['lChild']); //右节点 postOrderTraverse($node['rChild']); //输出值 print_r($node['data']); }
例子
<?php /** *二叉树的创建及基本操作 * *1.构造方法,初始化建立二叉树 *2.按先序遍历方式建立二叉树 *3.按先序遍历二叉树 *4.先序遍历的非递归算法 *5.中序遍历二叉树 *6.中序遍历的非递归算法 *7.后序遍历二叉树 *8.后序遍历非递归算法 *9.层次遍历二叉树 *10.求二叉树叶子结点的个数 *11.求二叉树的深度 *12.判断二叉树是否为空树 *13.置空二叉树 * *@author xudianyang<> *@version $Id:BinaryTree.class.php,v 1.0 2011/02/13 13:33:00 uw Exp *@copyright ©2011,xudianyang */ header('content-type:text/html;charset=gb2312'); //在PHP数据结构之五 栈的PHP的实现和栈的基本操作 可以找到该类 include_once ("./StackLinked.class.php"); //在 PHP数据结构之七 队列的链式存储和队列的基本操作 可以找到该类 include_once ('./QueueLinked.class.php'); class BTNode { //左子树“指针” public $mLchild = null; //右子树“指针” public $mRchild = null; //结点数据域 public $mData = null; //左标志域,为1时表示mLchild“指向”结点左孩子,为2表示“指向”结点直接前驱 public $intLeftTag = null; //右标志域,为1时表示mRchild“指向”结点右孩子,为2表示“指向”结点直接后继 public $intRightTag = null; } class BinaryTree { //根结点 public $mRoot; //根据先序遍历录入的二叉树数据 public $mPBTdata = null; /** *构造方法,初始化建立二叉树 * *@param array $btdata 根据先序遍历录入的二叉树的数据,一维数组,每一个元素代表二叉树一个结点值,扩充结点值为''[长度为0的字符串] *@return void */ public function __construct($btdata = array()) { $this->mPBTdata = $btdata; $this->mRoot = null; $this->getPreorderTraversalCreate($this->mRoot); } /** *按先序遍历方式建立二叉树 * *@param BTNode 二叉树结点,按引用方式传递 *@return void */ public function getPreorderTraversalCreate(&$btnode) { $elem = array_shift($this->mPBTdata); if ($elem === '') { $btnode = null; } else if ($elem === null) { return; } else { $btnode = new BTNode(); $btnode->mData = $elem; $this->getPreorderTraversalCreate($btnode->mLchild); $this->getPreorderTraversalCreate($btnode->mRchild); } } /** *判断二叉树是否为空 * *@return boolean 如果二叉树不空返回true,否则返回false * */ public function getIsEmpty() { if ($this->mRoot instanceof BTNode) { return false; } else { return true; } } /** *将二叉树置空 * *@return void */ public function setBinaryTreeNull() { $this->mRoot = null; } /** *按先序遍历二叉树 * *@param BTNode $rootnode 遍历过程中的根结点 *@param array $btarr 接收值的数组变量,按引用方式传递 *@return void */ public function getPreorderTraversal($rootnode, &$btarr) { if ($rootnode != null) { $btarr[] = $rootnode->mData; $this->getPreorderTraversal($rootnode->mLchild, $btarr); $this->getPreorderTraversal($rootnode->mRchild, $btarr); } } /** *先序遍历的非递归算法 * *@param BTNode $objRootNode 二叉树根节点 *@param array $arrBTdata 接收值的数组变量,按引用方式传递 *@return void */ public function getPreorderTraversalNoRecursion($objRootNode, &$arrBTdata) { if ($objRootNode instanceof BTNode) { $objNode = $objRootNode; $objStack = new StackLinked(); do { $arrBTdata[] = $objNode->mData; $objRNode = $objNode->mRchild; if ($objRNode != null) { $objStack->getPushStack($objRNode); } $objNode = $objNode->mLchild; if ($objNode == null) { $objStack->getPopStack($objNode); } } while ($objNode != null); } else { $arrBTdata = array(); } } /** *中序遍历二叉树 * *@param BTNode $objRootNode 过程中的根节点 *@param array $arrBTdata 接收值的数组变量,按引用方式传递 *@return void */ public function getInorderTraversal($objRootNode, &$arrBTdata) { if ($objRootNode != null) { $this->getInorderTraversal($objRootNode->mLchild, $arrBTdata); $arrBTdata[] = $objRootNode->mData; $this->getInorderTraversal($objRootNode->mRchild, $arrBTdata); } } /** *中序遍历的非递归算法 * *@param BTNode $objRootNode 二叉树根结点 *@param array $arrBTdata 接收值的数组变量,按引用方式传递 *@return void */ public function getInorderTraversalNoRecursion($objRootNode, &$arrBTdata) { if ($objRootNode instanceof BTNode) { $objNode = $objRootNode; $objStack = new StackLinked(); //中序遍历左子树及访问根节点 do { while ($objNode != null) { $objStack->getPushStack($objNode); $objNode = $objNode->mLchild; } $objStack->getPopStack($objNode); $arrBTdata[] = $objNode->mData; $objNode = $objNode->mRchild; } while (!$objStack->getIsEmpty()); //中序遍历右子树 do { while ($objNode != null) { $objStack->getPushStack($objNode); $objNode = $objNode->mLchild; } $objStack->getPopStack($objNode); $arrBTdata[] = $objNode->mData; $objNode = $objNode->mRchild; } while (!$objStack->getIsEmpty()); } else { $arrBTdata = array(); } } /** *后序遍历二叉树 * *@param BTNode $objRootNode 遍历过程中的根结点 *@param array $arrBTdata 接收值的数组变量,引用方式传递 *@return void */ public function getPostorderTraversal($objRootNode, &$arrBTdata) { if ($objRootNode != null) { $this->getPostorderTraversal($objRootNode->mLchild, $arrBTdata); $this->getPostorderTraversal($objRootNode->mRchild, $arrBTdata); $arrBTdata[] = $objRootNode->mData; } } /** *后序遍历非递归算法 * BTNode $objRootNode 二叉树根节点 array $arrBTdata 接收值的数组变量,按引用方式传递 void */ public function getPostorderTraversalNoRecursion($objRootNode, &$arrBTdata) { if ($objRootNode instanceof BTNode) { $objNode = $objRootNode; $objStack = new StackLinked(); $objTagStack = new StackLinked(); $tag = 1; do { while ($objNode != null) { $objStack->getPushStack($objNode); $objTagStack->getPushStack(1); $objNode = $objNode->mLchild; } $objTagStack->getPopStack($tag); $objTagStack->getPushStack($tag); if ($tag == 1) { $objStack->getPopStack($objNode); $objStack->getPushStack($objNode); $objNode = $objNode->mRchild; $objTagStack->getPopStack($tag); $objTagStack->getPushStack(2); } else { $objStack->getPopStack($objNode); $arrBTdata[] = $objNode->mData; $objTagStack->getPopStack($tag); $objNode = null; } } while (!$objStack->getIsEmpty()); } else { $arrBTdata = array(); } } /** *层次遍历二叉树 * *@param BTNode $objRootNode二叉树根节点 *@param array $arrBTdata 接收值的数组变量,按引用方式传递 *@return void */ public function getLevelorderTraversal($objRootNode, &$arrBTdata) { if ($objRootNode instanceof BTNode) { $objNode = $objRootNode; $objQueue = new QueueLinked(); $objQueue->getInsertElem($objNode); while (!$objQueue->getIsEmpty()) { $objQueue->getDeleteElem($objNode); $arrBTdata[] = $objNode->mData; if ($objNode->mLchild != null) { $objQueue->getInsertElem($objNode->mLchild); } if ($objNode->mRchild != null) { $objQueue->getInsertElem($objNode->mRchild); } } } else { $arrBTdata = array(); } } /** *求二叉树叶子结点的个数 * *@param BTNode $objRootNode 二叉树根节点 *@return int 参数传递错误返回-1 * */ public function getLeafNodeCount($objRootNode) { if ($objRootNode instanceof BTNode) { $intLeafNodeCount = 0; $objNode = $objRootNode; $objStack = new StackLinked(); do { if ($objNode->mLchild == null && $objNode->mRchild == null) { $intLeafNodeCount++; } $objRNode = $objNode->mRchild; if ($objRNode != null) { $objStack->getPushStack($objRNode); } $objNode = $objNode->mLchild; if ($objNode == null) { $objStack->getPopStack($objNode); } } while ($objNode != null); return $intLeafNodeCount; } else { return -1; } } /** *求二叉树的深度 * *@param BTNode $objRootNode 二叉树根节点 *@return int 参数传递错误返回-1 */ public function getBinaryTreeDepth($objRootNode) { if ($objRootNode instanceof BTNode) { $objNode = $objRootNode; $objQueue = new QueueLinked(); $intBinaryTreeDepth = 0; $objQueue->getInsertElem($objNode); $objLevel = $objNode; while (!$objQueue->getIsEmpty()) { $objQueue->getDeleteElem($objNode); if ($objNode->mLchild != null) { $objQueue->getInsertElem($objNode->mLchild); } if ($objNode->mRchild != null) { $objQueue->getInsertElem($objNode->mRchild); } if ($objLevel == $objNode) { $intBinaryTreeDepth++; $objLevel = @$objQueue->mRear->mElem; } } return $intBinaryTreeDepth; } else { return -1; } } } echo "<pre>"; $bt = new BinaryTree(array( 'A', 'B', 'D', '', '', 'E', '', 'G', '', '', 'C', 'F', '', '', '' )); echo "二叉树结构:\r\n"; var_dump($bt); $btarr = array(); echo "先序递归遍历二叉树:\r\n"; $bt->getPreorderTraversal($bt->mRoot, $btarr); var_dump($btarr); echo "先序非递归遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getPreorderTraversalNoRecursion($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "中序递归遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getInorderTraversal($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "中序非递归遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getInorderTraversalNoRecursion($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "后序递归遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getPostorderTraversal($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "后序非递归遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getPostorderTraversalNoRecursion($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "按层次遍历二叉树:\r\n"; $arrBTdata = array(); $bt->getLevelorderTraversal($bt->mRoot, $arrBTdata); var_dump($arrBTdata); echo "叶子结点的个数为:" . $bt->getLeafNodeCount($bt->mRoot); echo "\r\n"; echo "二叉树深度为:" . $bt->getBinaryTreeDepth($bt->mRoot); echo "\r\n"; echo "判断二叉树是否为空:"; var_dump($bt->getIsEmpty()); echo "将二叉树置空后:"; $bt->setBinaryTreeNull(); var_dump($bt); echo "</pre>"; ?>
永久链接:http://www.phprm.com/code/78085.html
转载随意!带上文章地址吧。