国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

php 二叉樹遍歷算法與例子

2024-05-04 21:49:42
字體:
來源:轉載
供稿:網友

二叉樹算法在小編大學時學數據結構時會學到的一個算法了,這個可以在搜索與排序中提高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.     } //開源軟件:Vevb.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. ?>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 威宁| 进贤县| 平阳县| 修文县| 绩溪县| 林甸县| 枣庄市| 信宜市| 哈密市| 平山县| 财经| 沿河| 兴安盟| 丹阳市| 随州市| 洛阳市| 临汾市| 繁昌县| 玉屏| 夏河县| 太仆寺旗| 民县| 酒泉市| 镇安县| 高阳县| 德惠市| 江陵县| 沧州市| 苏尼特左旗| 锡林郭勒盟| 涡阳县| 汾西县| 安岳县| 崇州市| 保康县| 河津市| 仙游县| 新野县| 筠连县| 镶黄旗| 华阴市|