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

PHP实现的线索二叉树及二叉树遍历方法详解

发布:smiling 来源: PHP粉丝网  添加日期:2019-08-18 14:40:10 浏览: 评论:0 

本文实例讲述了PHP实现的线索二叉树及二叉树遍历方法。分享给大家供大家参考,具体如下:

  1. <?php 
  2.  
  3.   require 'biTree.php'
  4.  
  5.   $str = 'ko#be8#tr####acy#####'
  6.  
  7.   $tree = new BiTree($str); 
  8.  
  9.   $tree->createThreadTree(); 
  10.  
  11.   echo $tree->threadList() . "\n";从第一个结点开始遍历线索二叉树 
  12.  
  13.   echo $tree->threadListReserv();从最后一个结点开始反向遍历 
  14.  
  15. ?> 

biTree.php:

  1. <? 
  2.  
  3.   /** 
  4.  
  5.    * PHP实现二叉树 
  6.  
  7.    * 
  8.  
  9.    * @author zhaojiangwei 
  10.  
  11.    * @since 2011/10/25 10:32 
  12.  
  13.    */ 
  14.  
  15.   //结点类 
  16.  
  17.   class Node{ 
  18.  
  19.     private $data = NULL; 
  20.  
  21.     private $left = NULL; 
  22.  
  23.     private $right = NULL; 
  24.  
  25.     private $lTag = 0; 
  26.  
  27.     private $rTag = 0; 
  28.  
  29.     public function Node($data = false){ 
  30.  
  31.       $this->data = $data
  32.  
  33.     } 
  34.  
  35.     //我不喜欢使用魔术方法 
  36.  
  37.     public function getData(){ 
  38.  
  39.       return $this->data; 
  40.  
  41.     } 
  42.  
  43.     public function setData($data){ 
  44.  
  45.       $this->data = $data
  46.  
  47.     } 
  48.  
  49.     public function getLeft(){ 
  50.  
  51.       return $this->left; 
  52.  
  53.     } 
  54.  
  55.     public function setLeft($left){ 
  56.  
  57.       $this->left = $left
  58.  
  59.     } 
  60.  
  61.     public function getRight(){ 
  62.  
  63.       return $this->right; 
  64.  
  65.     } 
  66.  
  67.     public function setRight($right){ 
  68.  
  69.       $this->right = $right
  70.  
  71.     } 
  72.  
  73.     public function getLTag(){ 
  74.  
  75.       return $this->lTag; 
  76.  
  77.     } 
  78.  
  79.     public function setLTag($tag){ 
  80.  
  81.       $this->lTag = $tag
  82.  
  83.     } 
  84.  
  85.     public function getRTag(){ 
  86.  
  87.       return $this->rTag; 
  88.  
  89.     } 
  90.  
  91.     public function setRTag($tag){ 
  92.  
  93.       $this->rTag = $tag
  94.  
  95.     } 
  96.  
  97.   } 
  98.  
  99.   //线索二叉树类 
  100.  
  101.   class BiTree{ 
  102.  
  103.     private $datas = NULL;//要导入的字符串; 
  104.  
  105.     private $root = NULL; //根结点 
  106.  
  107.     private $leafCount = 0;//叶子结点个数 
  108.  
  109.     private $headNode = NULL; //线索二叉树的头结点 
  110.  
  111.     private $preNode = NULL;//遍历线索化二叉树时保存前一个遍历的结点 
  112.  
  113.     public function BiTree($datas){ 
  114.  
  115.       is_array($datas) || $datas = str_split($datas); 
  116.  
  117.       $this->datas = $datas
  118.  
  119.       $this->backupData = $this->datas; 
  120.  
  121.       $this->createTree(TRUE); 
  122.  
  123.     } 
  124.  
  125.     //前序遍历创建树 
  126.  
  127.     //$root 判断是不是要创建根结点 
  128.  
  129.     public function createTree($root = FALSE){ 
  130.  
  131.       if(emptyempty($this->datas)) return NULL; 
  132.  
  133.       $first = array_shift($this->datas); 
  134.  
  135.       if($first == '#'){ 
  136.  
  137.         return NULL; 
  138.  
  139.       }else
  140.  
  141.         $node = new Node($first); 
  142.  
  143.         $root && $this->root = $node
  144.  
  145.         $node->setLeft($this->createTree()); 
  146.  
  147.         $node->setRight($this->createTree()); 
  148.  
  149.         return $node
  150.  
  151.       } 
  152.  
  153.     } 
  154.  
  155.     //返回二叉树叶子结点的个数 
  156.  
  157.     public function getLeafCount(){ 
  158.  
  159.       $this->figureLeafCount($this->root); 
  160.  
  161.       return $this->leafCount; 
  162.  
  163.     } 
  164.  
  165.     private function figureLeafCount($node){ 
  166.  
  167.       if($node == NULL) 
  168.  
  169.         return false; 
  170.  
  171.       if($this->checkEmpty($node)){ 
  172.  
  173.         $this->leafCount ++; 
  174.  
  175.       }else
  176.  
  177.         $this->figureLeafCount($node->getLeft()); 
  178.  
  179.         $this->figureLeafCount($node->getRight()); 
  180.  
  181.       } 
  182.  
  183.     } 
  184.  
  185.     //判断结点是不是叶子结点 
  186.  
  187.     private function checkEmpty($node){ 
  188.  
  189.       if($node->getLeft() == NULL && $node->getRight() == NULL){ 
  190.  
  191.         return true; 
  192.  
  193.       } 
  194.  
  195.       return false; 
  196.  
  197.     } 
  198.  
  199.     //返回二叉树深度 
  200.  
  201.     public function getDepth(){ 
  202.  
  203.       return $this->traversDepth($this->root); 
  204.  
  205.     } 
  206.  
  207.     //遍历求二叉树深度 
  208.  
  209.     public function traversDepth($node){ 
  210.  
  211.       if($node == NULL){ 
  212.  
  213.         return 0; 
  214.  
  215.       } 
  216.  
  217.       $u = $this->traversDepth($node->getLeft()) + 1; 
  218.  
  219.       $v = $this->traversDepth($node->getRight()) + 1; 
  220.  
  221.       return $u > $v ? $u : $v
  222.  
  223.     } 
  224.  
  225.     //返回遍历结果,以字符串的形式 
  226.  
  227.     //$order 按遍历形式返回,前中后 
  228.  
  229.     public function getList($order = 'front'){ 
  230.  
  231.       if($this->root == NULL) return NULL; 
  232.  
  233.       $nodeList = array(); 
  234.  
  235.       switch ($order){ 
  236.  
  237.         case "front"
  238.  
  239.           $this->frontList($this->root, $nodeList); 
  240.  
  241.           break
  242.  
  243.         case "middle"
  244.  
  245.           $this->middleList($this->root, $nodeList); 
  246.  
  247.           break
  248.  
  249.         case "last"
  250.  
  251.           $this->lastList($this->root, $nodeList); 
  252.  
  253.           break
  254.  
  255.         default
  256.  
  257.           $this->frontList($this->root, $nodeList); 
  258.  
  259.           break
  260.  
  261.       } 
  262.  
  263.       return implode($nodeList); 
  264.  
  265.     } 
  266.  
  267.     //创建线索二叉树 
  268.  
  269.     public function createThreadTree(){ 
  270.  
  271.       $this->headNode = new Node(); 
  272.  
  273.       $this->preNode = & $this->headNode; 
  274.  
  275.       $this->headNode->setLTag(0); 
  276.  
  277.       $this->headNode->setLeft($this->root); 
  278.  
  279.       $this->headNode->setRTag(1); 
  280.  
  281.       $this->threadTraverse($this->root); 
  282.  
  283.       $this->preNode->setRight($this->headNode); 
  284.  
  285.       $this->preNode->setRTag(1); 
  286.  
  287.       $this->headNode->setRight($this->preNode); 
  288.  
  289.     } 
  290.  
  291.     //线索化二叉树 
  292.  
  293.     private function threadTraverse($node){ 
  294.  
  295.       if($node != NULL){ 
  296.  
  297.         if($node->getLeft() == NULL){ 
  298.  
  299.           $node->setLTag(1); 
  300.  
  301.           $node->setLeft($this->preNode); 
  302.  
  303.         }else
  304.  
  305.           $this->threadTraverse($node->getLeft()); 
  306.  
  307.         } 
  308.  
  309.         if($this->preNode != $this->headNode && $this->preNode->getRight() == NULL){ 
  310.  
  311.           $this->preNode->setRTag(1); 
  312.  
  313.           $this->preNode->setRight($node); 
  314.  
  315.         } 
  316.  
  317.         $this->preNode = & $node;//注意传引用 
  318.  
  319.         $this->threadTraverse($node->getRight()); 
  320.  
  321.       } 
  322.  
  323.     } 
  324.  
  325.     //从第一个结点遍历中序线索二叉树 
  326.  
  327.     public function threadList(){ 
  328.  
  329.       $arr = array(); 
  330.  
  331.       for($node = $this->getFirstThreadNode($this->root); $node != $this->headNode; $node = $this->getNextNode($node)){ 
  332.  
  333.         $arr[] = $node->getData(); 
  334.  
  335.       } 
  336.  
  337.       return implode($arr); 
  338.  
  339.     } 
  340.  
  341.     //从尾结点反向遍历中序线索二叉树 
  342.  
  343.     public function threadListReserv(){ 
  344.  
  345.       $arr = array(); 
  346.  
  347.       for($node = $this->headNode->getRight(); $node != $this->headNode; $node = $this->getPreNode($node)){ 
  348.  
  349.         $arr[] = $node->getData(); 
  350.  
  351.       } 
  352.  
  353.       return implode($arr); 
  354.  
  355.     } 
  356.  
  357.     //返回某个结点的前驱 
  358.  
  359.     public function getPreNode($node){ 
  360.  
  361.       if($node->getLTag() == 1){ 
  362.  
  363.         return $node->getLeft(); 
  364.  
  365.       }else
  366.  
  367.         return $this->getLastThreadNode($node->getLeft()); 
  368.  
  369.       } 
  370.  
  371.     } 
  372.  
  373.     //返回某个结点的后继 
  374.  
  375.     public function getNextNode($node){ 
  376.  
  377.       if($node->getRTag() == 1){ 
  378.  
  379.         return $node->getRight(); 
  380.  
  381.       }else
  382.  
  383.         return $this->getFirstThreadNode($node->getRight()); 
  384.  
  385.       } 
  386.  
  387.     } 
  388.  
  389.     //返回中序线索二叉树的第一个结点 
  390.  
  391.     public function getFirstThreadNode($node){ 
  392.  
  393.       while($node->getLTag() == 0){ 
  394.  
  395.         $node = $node->getLeft(); 
  396.  
  397.       } 
  398.  
  399.       return $node
  400.  
  401.     } 
  402.  
  403.     //返回中序线索二叉树的最后一个结点 
  404.  
  405.     public function getLastThreadNode($node){ 
  406.  
  407.       while($node->getRTag() == 0){ 
  408.  
  409.         $node = $node->getRight(); 
  410.  
  411.       } 
  412.  
  413.       return $node
  414.  
  415.     } 
  416.  
  417.     //前序遍历 
  418.  
  419.     private function frontList($node, & $nodeList){ 
  420.  
  421.       if($node !== NULL){ 
  422.  
  423.         $nodeList[] = $node->getData(); 
  424.  
  425.         $this->frontList($node->getLeft(), $nodeList); 
  426.  
  427.         $this->frontList($node->getRight(), $nodeList); 
  428.  
  429.       } 
  430.  
  431.     } 
  432.  
  433.     //中序遍历 
  434.  
  435.     private function middleList($node, & $nodeList){ 
  436.  
  437.       if($node != NULL){ 
  438.  
  439.         $this->middleList($node->getLeft(), $nodeList); 
  440.  
  441.         $nodeList[] = $node->getData(); 
  442.  
  443.         $this->middleList($node->getRight(), $nodeList); 
  444.  
  445.       } 
  446.  
  447.     } 
  448.  
  449.     //后序遍历 
  450.  
  451.     private function lastList($node, & $nodeList){ 
  452.  
  453.       if($node != NULL){ 
  454.  
  455.         $this->lastList($node->getLeft(), $nodeList); 
  456.  
  457.         $this->lastList($node->getRight(), $nodeList); 
  458.  
  459.         $nodeList[] = $node->getData(); 
  460.  
  461.       } 
  462.  
  463.     } 
  464.  
  465.     public function getData(){ 
  466.  
  467.       return $this->data; 
  468. //phpfensi.com 
  469.     } 
  470.  
  471.     public function getRoot(){ 
  472.  
  473.       return $this->root; 
  474.  
  475.     } 
  476.  
  477.   } 
  478.  
  479. ?> 

Tags: PHP线索二叉树 PHP树遍历

分享到: