二叉樹算法在小編大學時學數據結構時會學到的一個算法了,這個可以在搜索與排序中提高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(emptyempty($node)){
- return;
- }
- //輸出值
- print_r($node['data']);
- //左節點
- PreOrderTraverse($node['lChild']);
- //右節點
- PreOrderTraverse($node['rChild']);
- }
- ?>
遍歷算法二:中序遍歷二叉樹
- <?php
- //中序遍歷二叉樹算法
- echo '中序遍歷二叉樹算法:';
- inOrderTraverse($arr);
- echo '<Br>';
- function inOrderTraverse($node){
- if(emptyempty($node)){
- return;
- }
- //左節點
- inOrderTraverse($node['lChild']);
- //輸出值
- print_r($node['data']);
- //右節點
- inOrderTraverse($node['rChild']);
- }
- ?>
遍歷算法三:后序遍歷二叉樹
- <?php
- //后序遍歷二叉樹算法
- echo '后序遍歷二叉樹算法:';
- postOrderTraverse($arr);
- echo '<Br>';
- function postOrderTraverse($node){
- if(emptyempty($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;
- } //開源軟件:Vevb.com
- }
- 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>";
- ?>
新聞熱點
疑難解答