首页 > php代码 > php 二叉树遍历算法与例子

php 二叉树遍历算法与例子

二叉树算法在小编大学时学数据结构时会学到的一个算法了,这个可以在搜索与排序中提高50%的搜索性能了,下面我们来看一些关于php 二叉树遍历算法与例子吧。

二叉树遍历,是值从根节点出发,按照某种次序依次访问二叉树中的所有节点,使得每个节点被访问一次且仅被访问依

tupan062.gif

 

图是百度搜的。。。谢谢提供图的英雄。。

前序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则先遍历左树,再遍历右树,遍历顺序为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 &copy;2011,xudianyang
 */
header('content-type:text/html;charset=gb2312');
//在PHP数据结构之五 栈的PHP的实现和栈的基本操作 可以找到该类
include_once ("./StackLinked.class.php");
//在 PHP数据结构之七 队列的链式存储和队列的基本操作 可以找到该类
include_once ('./QueueLinked.class.php');
class BTNode {
    //左子树&ldquo;指针&rdquo;
    public $mLchild = null;
    //右子树&ldquo;指针&rdquo;
    public $mRchild = null;
    //结点数据域
    public $mData = null; //左标志域,为1时表示mLchild&ldquo;指向&rdquo;结点左孩子,为2表示&ldquo;指向&rdquo;结点直接前驱
    public $intLeftTag = null;
    //右标志域,为1时表示mRchild&ldquo;指向&rdquo;结点右孩子,为2表示&ldquo;指向&rdquo;结点直接后继
    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

转载随意!带上文章地址吧。

标签:include

相关文章

发表留言