php 二叉樹遍曆演算法與例子

來源:互聯網
上載者:User

  二叉樹遍曆,是值從根節點出發,按照某種次序依次訪問二叉樹中的所有節點,使得每個節點被訪問一次且僅被訪問依

 

圖是百度搜的。。。謝謝提供圖的英雄。。

    前序走訪二叉樹:如果二叉樹為空白則返回,若二叉樹非空,則先遍曆左樹,再遍曆右樹,遍曆順序為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{
 //左子樹“指標”
 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>";
?>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.