当前位置:首页 > PHP教程 > php高级应用 > 列表

php 二叉树遍历算法与例子

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-08 13:54:43 浏览: 评论:0 

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

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

前序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则先遍历左树,再遍历右树,遍历顺序为ABCDEGF。

中序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从根节点开始,中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树,遍历顺序为CBEGDFA。

后序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从左到右先叶子后节点的访问遍历访问左右子树,最后是访问根节点。访问顺序为CGEFDBA。

层序遍历二叉树:如果二叉树为空则返回,若二叉树非空,则从树的第一层,也就是根节点开始访问,从上而下逐层遍历,在同一层中,按照从左到右的顺序对节点逐个访问。访问顺序为ABCDEFG。

现在,我们用PHP代码,来遍历二叉树结构,二叉树是放一个大数组,每一个节点都有三个字段,data表示这个节点的值,lChild表示这个节点的左边子节点,rChild表示这个节点的右边子节点.

二叉树结构代码如下:

  1. <?php 
  2. //二叉树 
  3. $arr = array
  4.     'data' => 'A'
  5.     'lChild' => array
  6.         'data' => 'B'
  7.         'lChild' => array
  8.             'data' => 'C'
  9.             'lChild' => array(), 
  10.             'rChild' => array(), 
  11.         ), 
  12.         'rChild' => array
  13.             'data' => 'D'
  14.             'lChild' => array
  15.                 'data' => 'E'
  16.                 'lChild' => array(), 
  17.                 'rChild' => array
  18.                     'data' => 'G'
  19.                     'lChild' => array(), 
  20.                     'rChild' => array(), 
  21.                 ), 
  22.             ), 
  23.             'rChild' => array
  24.                 'data' => 'F'
  25.                 'lChild' => array(), 
  26.                 'rChild' => array(), 
  27.             ), 
  28.         ), 
  29.     ), 
  30.     'rChild' => array(), 
  31. ); 
  32. ?> 

遍历算法一:前序遍历二叉树

  1. <?php 
  2. //前序遍历二叉树算法 
  3. echo '前序遍历二叉树算法:'
  4. PreOrderTraverse($arr); 
  5. echo '<Br>'
  6. function PreOrderTraverse($node){ 
  7.     if(emptyempty($node)){ 
  8.         return
  9.     } 
  10.     //输出值 
  11.     print_r($node['data']); 
  12.     //左节点 
  13.     PreOrderTraverse($node['lChild']); 
  14.     //右节点 
  15.     PreOrderTraverse($node['rChild']); 
  16. ?> 

遍历算法二:中序遍历二叉树

  1. <?php 
  2. //中序遍历二叉树算法 
  3. echo '中序遍历二叉树算法:'
  4. inOrderTraverse($arr); 
  5. echo '<Br>'
  6. function inOrderTraverse($node){ 
  7.     if(emptyempty($node)){ 
  8.         return
  9.     } 
  10.     //左节点 
  11.     inOrderTraverse($node['lChild']); 
  12.     //输出值 
  13.     print_r($node['data']); 
  14.     //右节点 
  15.     inOrderTraverse($node['rChild']); 
  16. ?> 

遍历算法三:后序遍历二叉树

  1. <?php 
  2. //后序遍历二叉树算法 
  3. echo '后序遍历二叉树算法:'
  4. postOrderTraverse($arr); 
  5. echo '<Br>'
  6. function postOrderTraverse($node){ 
  7.     if(emptyempty($node)){ 
  8.         return
  9.     } 
  10.     //左节点 
  11.     postOrderTraverse($node['lChild']); 
  12.     //右节点 
  13.     postOrderTraverse($node['rChild']); 
  14.     //输出值 
  15.     print_r($node['data']); 
  16. ?> 

例子:

  1. <?php 
  2. /** 
  3.  *二叉树的创建及基本操作 
  4.  * 
  5.  *1.构造方法,初始化建立二叉树 
  6.  *2.按先序遍历方式建立二叉树 
  7.  *3.按先序遍历二叉树 
  8.  *4.先序遍历的非递归算法 
  9.  *5.中序遍历二叉树 
  10.  *6.中序遍历的非递归算法 
  11.  *7.后序遍历二叉树 
  12.  *8.后序遍历非递归算法 
  13.  *9.层次遍历二叉树 
  14.  *10.求二叉树叶子结点的个数 
  15.  *11.求二叉树的深度 
  16.  *12.判断二叉树是否为空树 
  17.  *13.置空二叉树 
  18.  * 
  19.  *@author xudianyang<> 
  20.  *@version $Id:BinaryTree.class.php,v 1.0 2011/02/13 13:33:00 uw Exp 
  21.  *@copyright &copy;2011,xudianyang 
  22.  */ 
  23. header('content-type:text/html;charset=gb2312'); 
  24. //在PHP数据结构之五 栈的PHP的实现和栈的基本操作 可以找到该类 
  25. include_once("./StackLinked.class.php"); 
  26. //在 PHP数据结构之七 队列的链式存储和队列的基本操作 可以找到该类 
  27. include_once('./QueueLinked.class.php'); 
  28. class BTNode{ 
  29.  //左子树“指针” 
  30.  public $mLchild=null
  31.  //右子树“指针” 
  32.  public $mRchild=null
  33.  //结点数据域 
  34.  public $mData=null//左标志域,为1时表示mLchild“指向”结点左孩子,为2表示“指向”结点直接前驱 
  35.  public $intLeftTag=null
  36.  //右标志域,为1时表示mRchild“指向”结点右孩子,为2表示“指向”结点直接后继 
  37.  public $intRightTag=null
  38. class BinaryTree{ 
  39.  //根结点 
  40.  public $mRoot; 
  41.  //根据先序遍历录入的二叉树数据 
  42.  public $mPBTdata=null
  43.  /** 
  44.   *构造方法,初始化建立二叉树 
  45.   * 
  46.   *@param array $btdata 根据先序遍历录入的二叉树的数据,一维数组,每一个元素代表二叉树一个结点值,扩充结点值为''[长度为0的字符串] 
  47.   *@return void 
  48.   */ 
  49.  public function __construct($btdata=array()){ 
  50.   $this->mPBTdata=$btdata; 
  51.   $this->mRoot=null
  52.   $this->getPreorderTraversalCreate($this->mRoot); 
  53.  } 
  54.  /** 
  55.   *按先序遍历方式建立二叉树 
  56.   * 
  57.   *@param BTNode 二叉树结点,按引用方式传递 
  58.   *@return void 
  59.   */ 
  60.  public function getPreorderTraversalCreate(&$btnode){ 
  61.   $elem=array_shift($this->mPBTdata); 
  62.   if($elem === ''){ 
  63.    $btnode=null
  64.   }else if($elem === null){ 
  65.    return
  66.   }else
  67.    $btnode=new BTNode(); 
  68.    $btnode->mData=$elem; 
  69.    $this->getPreorderTraversalCreate($btnode->mLchild); 
  70.    $this->getPreorderTraversalCreate($btnode->mRchild); 
  71.   } 
  72.  } 
  73.  /** 
  74.   *判断二叉树是否为空 
  75.   * 
  76.   *@return boolean 如果二叉树不空返回true,否则返回false 
  77.   **/ 
  78.  public function getIsEmpty(){ 
  79.   if($this->mRoot instanceof BTNode){ 
  80.    return false
  81.   }else
  82.    return true
  83.   } 
  84.  } 
  85.  /** 
  86.   *将二叉树置空 
  87.   * 
  88.   *@return void 
  89.   */ 
  90.  public function setBinaryTreeNull(){ 
  91.   $this->mRoot=null
  92.  } 
  93.  /** 
  94.   *按先序遍历二叉树 
  95.   * 
  96.   *@param BTNode $rootnode 遍历过程中的根结点 
  97.   *@param array $btarr 接收值的数组变量,按引用方式传递 
  98.   *@return void 
  99.   */ 
  100.  public function getPreorderTraversal($rootnode,&$btarr){ 
  101.   if($rootnode!=null){ 
  102.    $btarr[]=$rootnode->mData; 
  103.    $this->getPreorderTraversal($rootnode->mLchild,$btarr); 
  104.    $this->getPreorderTraversal($rootnode->mRchild,$btarr); 
  105.   } 
  106.  } 
  107.  /** 
  108.   *先序遍历的非递归算法 
  109.   * 
  110.   *@param BTNode $objRootNode 二叉树根节点 
  111.   *@param array $arrBTdata 接收值的数组变量,按引用方式传递 
  112.   *@return void 
  113.   */ 
  114.  public function getPreorderTraversalNoRecursion($objRootNode,&$arrBTdata){ 
  115.   if($objRootNode instanceof BTNode){ 
  116.    $objNode=$objRootNode; 
  117.    $objStack=new StackLinked(); 
  118.    do
  119.     $arrBTdata[]=$objNode->mData; 
  120.     $objRNode=$objNode->mRchild; 
  121.     if($objRNode !=null){ 
  122.      $objStack->getPushStack($objRNode); 
  123.     } 
  124.     $objNode=$objNode->mLchild; 
  125.     if($objNode==null){ 
  126.      $objStack->getPopStack($objNode); 
  127.     } 
  128.    }while($objNode!=null); 
  129.   }else
  130.    $arrBTdata=array(); 
  131.   } 
  132.  } 
  133.  /** 
  134.   *中序遍历二叉树 
  135.   * 
  136.   *@param BTNode $objRootNode 过程中的根节点 
  137.   *@param array $arrBTdata 接收值的数组变量,按引用方式传递 
  138.   *@return void 
  139.   */ 
  140.  public function getInorderTraversal($objRootNode,&$arrBTdata){ 
  141.   if($objRootNode!=null){ 
  142.    $this->getInorderTraversal($objRootNode->mLchild,$arrBTdata); 
  143.    $arrBTdata[]=$objRootNode->mData; 
  144.    $this->getInorderTraversal($objRootNode->mRchild,$arrBTdata); 
  145.   } 
  146.  } 
  147.  /** 
  148.   *中序遍历的非递归算法 
  149.   * 
  150.   *@param BTNode $objRootNode 二叉树根结点 
  151.   *@param array $arrBTdata 接收值的数组变量,按引用方式传递 
  152.   *@return void 
  153.   */ 
  154.  public function getInorderTraversalNoRecursion($objRootNode,&$arrBTdata){ 
  155.   if($objRootNode instanceof BTNode){ 
  156.    $objNode=$objRootNode; 
  157.    $objStack=new StackLinked(); 
  158.    //中序遍历左子树及访问根节点 
  159.    do
  160.     while($objNode!=null){ 
  161.      $objStack->getPushStack($objNode); 
  162.      $objNode=$objNode->mLchild; 
  163.     } 
  164.     $objStack->getPopStack($objNode); 
  165.     $arrBTdata[]=$objNode->mData; 
  166.     $objNode=$objNode->mRchild; 
  167.    }while(!$objStack->getIsEmpty()); 
  168.    //中序遍历右子树 
  169.    do
  170.     while($objNode!=null){ 
  171.      $objStack->getPushStack($objNode); 
  172.      $objNode=$objNode->mLchild; 
  173.     } 
  174.     $objStack->getPopStack($objNode); 
  175.     $arrBTdata[]=$objNode->mData; 
  176.     $objNode=$objNode->mRchild; 
  177.    }while(!$objStack->getIsEmpty()); 
  178.   }else
  179.    $arrBTdata=array(); 
  180.   } 
  181.  } 
  182.  /** 
  183.   *后序遍历二叉树 
  184.   * 
  185.   *@param BTNode $objRootNode  遍历过程中的根结点 
  186.   *@param array $arrBTdata 接收值的数组变量,引用方式传递 
  187.   *@return void 
  188.   */ 
  189.  public function getPostorderTraversal($objRootNode,&$arrBTdata){ 
  190.   if($objRootNode!=null){ 
  191.    $this->getPostorderTraversal($objRootNode->mLchild,$arrBTdata); 
  192.    $this->getPostorderTraversal($objRootNode->mRchild,$arrBTdata); 
  193.    $arrBTdata[]=$objRootNode->mData; 
  194.   } 
  195.  } 
  196.  /** 
  197.   *后序遍历非递归算法 
  198.   * 
  199.  BTNode $objRootNode 二叉树根节点 
  200.  array $arrBTdata 接收值的数组变量,按引用方式传递 
  201.  void 
  202.   */ 
  203.  public function getPostorderTraversalNoRecursion($objRootNode,&$arrBTdata){ 
  204.   if($objRootNode instanceof BTNode){ 
  205.    $objNode=$objRootNode; 
  206.    $objStack=new StackLinked(); 
  207.    $objTagStack=new StackLinked(); 
  208.    $tag=1; 
  209.    do
  210.     while($objNode!=null){ 
  211.      $objStack->getPushStack($objNode); 
  212.      $objTagStack->getPushStack(1); 
  213.      $objNode=$objNode->mLchild; 
  214.     } 
  215.     $objTagStack->getPopStack($tag); 
  216.     $objTagStack->getPushStack($tag); 
  217.     if($tag == 1){ 
  218.      $objStack->getPopStack($objNode); 
  219.      $objStack->getPushStack($objNode); 
  220.      $objNode=$objNode->mRchild; 
  221.      $objTagStack->getPopStack($tag); 
  222.      $objTagStack->getPushStack(2); 
  223.     }else
  224.      $objStack->getPopStack($objNode); 
  225.      $arrBTdata[]=$objNode->mData; 
  226.      $objTagStack->getPopStack($tag); 
  227.      $objNode=null
  228.     } 
  229.    }while(!$objStack->getIsEmpty()); 
  230.   }else
  231.    $arrBTdata=array(); 
  232.   } 
  233.  } 
  234.  /** 
  235.   *层次遍历二叉树 
  236.   * 
  237.   *@param BTNode $objRootNode二叉树根节点 
  238.   *@param array $arrBTdata 接收值的数组变量,按引用方式传递 
  239.   *@return void 
  240.   */ 
  241.  public function getLevelorderTraversal($objRootNode,&$arrBTdata){ 
  242.   if($objRootNode instanceof BTNode){ 
  243.    $objNode=$objRootNode; 
  244.    $objQueue=new QueueLinked(); 
  245.    $objQueue->getInsertElem($objNode); 
  246.    while(!$objQueue->getIsEmpty()){ 
  247.     $objQueue->getDeleteElem($objNode); 
  248.     $arrBTdata[]=$objNode->mData; 
  249.     if($objNode->mLchild != null){ 
  250.      $objQueue->getInsertElem($objNode->mLchild); 
  251.     } 
  252.     if($objNode->mRchild != null){ 
  253.      $objQueue->getInsertElem($objNode->mRchild); 
  254.     } 
  255.    } 
  256.   }else
  257.    $arrBTdata=array(); 
  258.   } 
  259.  } 
  260.  /** 
  261.   *求二叉树叶子结点的个数 
  262.   * 
  263.   *@param BTNode $objRootNode 二叉树根节点 
  264.   *@return int 参数传递错误返回-1 
  265.   **/ 
  266.  public function getLeafNodeCount($objRootNode){ 
  267.   if($objRootNode instanceof BTNode){ 
  268.    $intLeafNodeCount=0; 
  269.    $objNode=$objRootNode; 
  270.    $objStack=new StackLinked(); 
  271.    do
  272.     if($objNode->mLchild == null && $objNode->mRchild == null){ 
  273.      $intLeafNodeCount++; 
  274.     } 
  275.     $objRNode=$objNode->mRchild; 
  276.     if($objRNode != null){ 
  277.      $objStack->getPushStack($objRNode); 
  278.     } 
  279.     $objNode=$objNode->mLchild; 
  280.     if($objNode == null){ 
  281.      $objStack->getPopStack($objNode); 
  282.     } 
  283.    }while($objNode != null); 
  284.    return $intLeafNodeCount; 
  285.   }else
  286.    return -1; 
  287.   } 
  288.  } 
  289.  /** 
  290.   *求二叉树的深度 
  291.   * 
  292.   *@param BTNode $objRootNode 二叉树根节点 
  293.   *@return int 参数传递错误返回-1 
  294.   */ 
  295.  public function getBinaryTreeDepth($objRootNode){ 
  296.   if($objRootNode instanceof BTNode){ 
  297.    $objNode=$objRootNode; 
  298.    $objQueue=new QueueLinked(); 
  299.    $intBinaryTreeDepth=0; 
  300.    $objQueue->getInsertElem($objNode); 
  301.    $objLevel=$objNode; 
  302.    while(!$objQueue->getIsEmpty()){ 
  303.     $objQueue->getDeleteElem($objNode); 
  304.     if($objNode->mLchild != null){ 
  305.      $objQueue->getInsertElem($objNode->mLchild); 
  306.     } 
  307.     if($objNode->mRchild != null){ 
  308.      $objQueue->getInsertElem($objNode->mRchild); 
  309.     } 
  310.     if($objLevel == $objNode){ 
  311.      $intBinaryTreeDepth++; 
  312.      $objLevel=@$objQueue->mRear->mElem; 
  313.     } //开源软件:phpfensi.com 
  314.    } 
  315.    return $intBinaryTreeDepth; 
  316.   }else
  317.    return -1; 
  318.   } 
  319.  } 
  320. echo "<pre>"
  321. $bt=new BinaryTree(array('A','B','D','','','E','','G','','','C','F','','','')); 
  322. echo "二叉树结构:\r\n"
  323. var_dump($bt); 
  324. $btarr=array(); 
  325. echo "先序递归遍历二叉树:\r\n"
  326. $bt->getPreorderTraversal($bt->mRoot,$btarr); 
  327. var_dump($btarr); 
  328. echo "先序非递归遍历二叉树:\r\n"
  329. $arrBTdata=array(); 
  330. $bt->getPreorderTraversalNoRecursion($bt->mRoot,$arrBTdata); 
  331. var_dump($arrBTdata); 
  332. echo "中序递归遍历二叉树:\r\n"
  333. $arrBTdata=array(); 
  334. $bt->getInorderTraversal($bt->mRoot,$arrBTdata); 
  335. var_dump($arrBTdata); 
  336. echo "中序非递归遍历二叉树:\r\n"
  337. $arrBTdata=array(); 
  338. $bt->getInorderTraversalNoRecursion($bt->mRoot,$arrBTdata); 
  339. var_dump($arrBTdata); 
  340. echo "后序递归遍历二叉树:\r\n"
  341. $arrBTdata=array(); 
  342. $bt->getPostorderTraversal($bt->mRoot,$arrBTdata); 
  343. var_dump($arrBTdata); 
  344. echo "后序非递归遍历二叉树:\r\n"
  345. $arrBTdata=array(); 
  346. $bt->getPostorderTraversalNoRecursion($bt->mRoot,$arrBTdata); 
  347. var_dump($arrBTdata); 
  348. echo "按层次遍历二叉树:\r\n"
  349. $arrBTdata=array(); 
  350. $bt->getLevelorderTraversal($bt->mRoot,$arrBTdata); 
  351. var_dump($arrBTdata); 
  352. echo "叶子结点的个数为:".$bt->getLeafNodeCount($bt->mRoot); 
  353. echo "\r\n"
  354. echo "二叉树深度为:".$bt->getBinaryTreeDepth($bt->mRoot); 
  355. echo "\r\n"
  356. echo "判断二叉树是否为空:"
  357. var_dump($bt->getIsEmpty()); 
  358. echo "将二叉树置空后:"
  359. $bt->setBinaryTreeNull(); 
  360. var_dump($bt); 
  361. echo "</pre>"
  362. ?>

Tags: php二叉树 php遍历算法

分享到: