A-A+

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

2019年08月20日 我爱编程 暂无评论

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

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

biTree.php:

  1. <?
  2.   /**
  3.    * PHP实现二叉树
  4.    *
  5.    * @author
  6.    * @since 2011/10/25 10:32
  7.    */
  8.   //结点类
  9.   class Node{
  10.     private $data = NULL;
  11.     private $left = NULL;
  12.     private $right = NULL;
  13.     private $lTag = 0;
  14.     private $rTag = 0;
  15.     public function Node($data = false){
  16.       $this->data = $data;
  17.     }
  18.     //我不喜欢使用魔术方法
  19.     public function getData(){
  20.       return $this->data;
  21.     }
  22.     public function setData($data){
  23.       $this->data = $data;
  24.     }
  25.     public function getLeft(){
  26.       return $this->left;
  27.     }
  28.     public function setLeft($left){
  29.       $this->left = $left;
  30.     }
  31.     public function getRight(){
  32.       return $this->right;
  33.     }
  34.     public function setRight($right){
  35.       $this->right = $right;
  36.     }
  37.     public function getLTag(){
  38.       return $this->lTag;
  39.     }
  40.     public function setLTag($tag){
  41.       $this->lTag = $tag;
  42.     }
  43.     public function getRTag(){
  44.       return $this->rTag;
  45.     }
  46.     public function setRTag($tag){
  47.       $this->rTag = $tag;
  48.     }
  49.   }
  50.   //线索二叉树类
  51.   class BiTree{
  52.     private $datas = NULL;//要导入的字符串;
  53.     private $root = NULL; //根结点
  54.     private $leafCount = 0;//叶子结点个数
  55.     private $headNode = NULL; //线索二叉树的头结点
  56.     private $preNode = NULL;//遍历线索化二叉树时保存前一个遍历的结点
  57.     public function BiTree($datas){
  58.       is_array($datas) || $datas = str_split($datas);
  59.       $this->datas = $datas;
  60.       $this->backupData = $this->datas;
  61.       $this->createTree(TRUE);
  62.     }
  63.     //前序遍历创建树
  64.     //$root 判断是不是要创建根结点
  65.     public function createTree($root = FALSE){
  66.       if(emptyempty($this->datas)) return NULL;
  67.       $first = array_shift($this->datas);
  68.       if($first == '#'){
  69.         return NULL;
  70.       }else{
  71.         $node = new Node($first);
  72.         $root && $this->root = $node;
  73.         $node->setLeft($this->createTree());
  74.         $node->setRight($this->createTree());
  75.         return $node;
  76.       }
  77.     }
  78.     //返回二叉树叶子结点的个数
  79.     public function getLeafCount(){
  80.       $this->figureLeafCount($this->root);
  81.       return $this->leafCount;
  82.     }
  83.     private function figureLeafCount($node){
  84.       if($node == NULL)
  85.         return false;
  86.       if($this->checkEmpty($node)){
  87.         $this->leafCount ++;
  88.       }else{
  89.         $this->figureLeafCount($node->getLeft());
  90.         $this->figureLeafCount($node->getRight());
  91.       }
  92.     }
  93.     //判断结点是不是叶子结点
  94.     private function checkEmpty($node){
  95.       if($node->getLeft() == NULL && $node->getRight() == NULL){
  96.         return true;
  97.       }
  98.       return false;
  99.     }
  100.     //返回二叉树深度
  101.     public function getDepth(){
  102.       return $this->traversDepth($this->root);
  103.     }
  104.     //遍历求二叉树深度
  105.     public function traversDepth($node){
  106.       if($node == NULL){
  107.         return 0;
  108.       }
  109.       $u = $this->traversDepth($node->getLeft()) + 1;
  110.       $v = $this->traversDepth($node->getRight()) + 1;
  111.       return $u > $v ? $u : $v;
  112.     }
  113.     //返回遍历结果,以字符串的形式
  114.     //$order 按遍历形式返回,前中后
  115.     public function getList($order = 'front'){
  116.       if($this->root == NULL) return NULL;
  117.       $nodeList = array();
  118.       switch ($order){
  119.         case "front":
  120.           $this->frontList($this->root, $nodeList);
  121.           break;
  122.         case "middle":
  123.           $this->middleList($this->root, $nodeList);
  124.           break;
  125.         case "last":
  126.           $this->lastList($this->root, $nodeList);
  127.           break;
  128.         default:
  129.           $this->frontList($this->root, $nodeList);
  130.           break;
  131.       }
  132.       return implode($nodeList);
  133.     }
  134.     //创建线索二叉树
  135.     public function createThreadTree(){
  136.       $this->headNode = new Node();
  137.       $this->preNode = & $this->headNode;
  138.       $this->headNode->setLTag(0);
  139.       $this->headNode->setLeft($this->root);
  140.       $this->headNode->setRTag(1);
  141.       $this->threadTraverse($this->root);
  142.       $this->preNode->setRight($this->headNode);
  143.       $this->preNode->setRTag(1);
  144.       $this->headNode->setRight($this->preNode);
  145.     }
  146.     //线索化二叉树
  147.     private function threadTraverse($node){
  148.       if($node != NULL){
  149.         if($node->getLeft() == NULL){
  150.           $node->setLTag(1);
  151.           $node->setLeft($this->preNode);
  152.         }else{
  153.           $this->threadTraverse($node->getLeft());
  154.         }
  155.         if($this->preNode != $this->headNode && $this->preNode->getRight() == NULL){
  156.           $this->preNode->setRTag(1);
  157.           $this->preNode->setRight($node);
  158.         }
  159.         $this->preNode = & $node;//注意传引用
  160.         $this->threadTraverse($node->getRight());
  161.       }
  162.     }
  163.     //从第一个结点遍历中序线索二叉树
  164.     public function threadList(){
  165.       $arr = array();
  166.       for($node = $this->getFirstThreadNode($this->root); $node != $this->headNode; $node = $this->getNextNode($node)){
  167.         $arr[] = $node->getData();
  168.       }
  169.       return implode($arr);
  170.     }
  171.     //从尾结点反向遍历中序线索二叉树
  172.     public function threadListReserv(){
  173.       $arr = array();
  174.       for($node = $this->headNode->getRight(); $node != $this->headNode; $node = $this->getPreNode($node)){
  175.         $arr[] = $node->getData();
  176.       }
  177.       return implode($arr);
  178.     }
  179.     //返回某个结点的前驱
  180.     public function getPreNode($node){
  181.       if($node->getLTag() == 1){
  182.         return $node->getLeft();
  183.       }else{
  184.         return $this->getLastThreadNode($node->getLeft());
  185.       }
  186.     }
  187.     //返回某个结点的后继
  188.     public function getNextNode($node){
  189.       if($node->getRTag() == 1){
  190.         return $node->getRight();
  191.       }else{
  192.         return $this->getFirstThreadNode($node->getRight());
  193.       }
  194.     }
  195.     //返回中序线索二叉树的第一个结点
  196.     public function getFirstThreadNode($node){
  197.       while($node->getLTag() == 0){
  198.         $node = $node->getLeft();
  199.       }
  200.       return $node;
  201.     }
  202.     //返回中序线索二叉树的最后一个结点
  203.     public function getLastThreadNode($node){
  204.       while($node->getRTag() == 0){
  205.         $node = $node->getRight();
  206.       }
  207.       return $node;
  208.     }
  209.     //前序遍历
  210.     private function frontList($node, & $nodeList){
  211.       if($node !== NULL){
  212.         $nodeList[] = $node->getData();
  213.         $this->frontList($node->getLeft(), $nodeList);
  214.         $this->frontList($node->getRight(), $nodeList);
  215.       }
  216.     }
  217.     //中序遍历
  218.     private function middleList($node, & $nodeList){
  219.       if($node != NULL){
  220.         $this->middleList($node->getLeft(), $nodeList);
  221.         $nodeList[] = $node->getData();
  222.         $this->middleList($node->getRight(), $nodeList);
  223.       }
  224.     }
  225.     //后序遍历
  226.     private function lastList($node, & $nodeList){
  227.       if($node != NULL){
  228.         $this->lastList($node->getLeft(), $nodeList);
  229.         $this->lastList($node->getRight(), $nodeList);
  230.         $nodeList[] = $node->getData();
  231.       }
  232.     }
  233.     public function getData(){
  234.       return $this->data;
  235.     }
  236.     public function getRoot(){
  237.       return $this->root;
  238.     }
  239.   }
  240. ?>

给我留言

Copyright © 四季博客 保留所有权利.   Theme  Ality

用户登录