二叉樹遍曆,是值從根節點出發,按照某種次序依次訪問二叉樹中的所有節點,使得每個節點被訪問一次且僅被訪問依
圖是百度搜的。。。謝謝提供圖的英雄。。
前序走訪二叉樹:如果二叉樹為空白則返回,若二叉樹非空,則先遍曆左樹,再遍曆右樹,遍曆順序為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>";
?>