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

 更新时间:2016年04月25日 09:23:23   作者:z32556601  
这篇文章主要介绍了PHP实现的线索二叉树及二叉树遍历方法,结合实例形式较为详细的分析了线索二叉树的定义,创建,判断与遍历等技巧,需要的朋友可以参考下

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

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

biTree.php:

<?
  /**
   * PHP实现二叉树
   *
   * @author zhaojiangwei
   * @since 2011/10/25 10:32
   */
  //结点类
  class Node{
    private $data = NULL;
    private $left = NULL;
    private $right = NULL;
    private $lTag = 0;
    private $rTag = 0;
    public function Node($data = false){
      $this->data = $data;
    }
    //我不喜欢使用魔术方法
    public function getData(){
      return $this->data;
    }
    public function setData($data){
      $this->data = $data;
    }
    public function getLeft(){
      return $this->left;
    }
    public function setLeft($left){
      $this->left = $left;
    }
    public function getRight(){
      return $this->right;
    }
    public function setRight($right){
      $this->right = $right;
    }
    public function getLTag(){
      return $this->lTag;
    }
    public function setLTag($tag){
      $this->lTag = $tag;
    }
    public function getRTag(){
      return $this->rTag;
    }
    public function setRTag($tag){
      $this->rTag = $tag;
    }
  }
  //线索二叉树类
  class BiTree{
    private $datas = NULL;//要导入的字符串;
    private $root = NULL; //根结点
    private $leafCount = 0;//叶子结点个数
    private $headNode = NULL; //线索二叉树的头结点
    private $preNode = NULL;//遍历线索化二叉树时保存前一个遍历的结点
    public function BiTree($datas){
      is_array($datas) || $datas = str_split($datas);
      $this->datas = $datas;
      $this->backupData = $this->datas;
      $this->createTree(TRUE);
    }
    //前序遍历创建树
    //$root 判断是不是要创建根结点
    public function createTree($root = FALSE){
      if(emptyempty($this->datas)) return NULL;
      $first = array_shift($this->datas);
      if($first == '#'){
        return NULL;
      }else{
        $node = new Node($first);
        $root && $this->root = $node;
        $node->setLeft($this->createTree());
        $node->setRight($this->createTree());
        return $node;
      }
    }
    //返回二叉树叶子结点的个数
    public function getLeafCount(){
      $this->figureLeafCount($this->root);
      return $this->leafCount;
    }
    private function figureLeafCount($node){
      if($node == NULL)
        return false;
      if($this->checkEmpty($node)){
        $this->leafCount ++;
      }else{
        $this->figureLeafCount($node->getLeft());
        $this->figureLeafCount($node->getRight());
      }
    }
    //判断结点是不是叶子结点
    private function checkEmpty($node){
      if($node->getLeft() == NULL && $node->getRight() == NULL){
        return true;
      }
      return false;
    }
    //返回二叉树深度
    public function getDepth(){
      return $this->traversDepth($this->root);
    }
    //遍历求二叉树深度
    public function traversDepth($node){
      if($node == NULL){
        return 0;
      }
      $u = $this->traversDepth($node->getLeft()) + 1;
      $v = $this->traversDepth($node->getRight()) + 1;
      return $u > $v ? $u : $v;
    }
    //返回遍历结果,以字符串的形式
    //$order 按遍历形式返回,前中后
    public function getList($order = 'front'){
      if($this->root == NULL) return NULL;
      $nodeList = array();
      switch ($order){
        case "front":
          $this->frontList($this->root, $nodeList);
          break;
        case "middle":
          $this->middleList($this->root, $nodeList);
          break;
        case "last":
          $this->lastList($this->root, $nodeList);
          break;
        default:
          $this->frontList($this->root, $nodeList);
          break;
      }
      return implode($nodeList);
    }
    //创建线索二叉树
    public function createThreadTree(){
      $this->headNode = new Node();
      $this->preNode = & $this->headNode;
      $this->headNode->setLTag(0);
      $this->headNode->setLeft($this->root);
      $this->headNode->setRTag(1);
      $this->threadTraverse($this->root);
      $this->preNode->setRight($this->headNode);
      $this->preNode->setRTag(1);
      $this->headNode->setRight($this->preNode);
    }
    //线索化二叉树
    private function threadTraverse($node){
      if($node != NULL){
        if($node->getLeft() == NULL){
          $node->setLTag(1);
          $node->setLeft($this->preNode);
        }else{
          $this->threadTraverse($node->getLeft());
        }
        if($this->preNode != $this->headNode && $this->preNode->getRight() == NULL){
          $this->preNode->setRTag(1);
          $this->preNode->setRight($node);
        }
        $this->preNode = & $node;//注意传引用
        $this->threadTraverse($node->getRight());
      }
    }
    //从第一个结点遍历中序线索二叉树
    public function threadList(){
      $arr = array();
      for($node = $this->getFirstThreadNode($this->root); $node != $this->headNode; $node = $this->getNextNode($node)){
        $arr[] = $node->getData();
      }
      return implode($arr);
    }
    //从尾结点反向遍历中序线索二叉树
    public function threadListReserv(){
      $arr = array();
      for($node = $this->headNode->getRight(); $node != $this->headNode; $node = $this->getPreNode($node)){
        $arr[] = $node->getData();
      }
      return implode($arr);
    }
    //返回某个结点的前驱
    public function getPreNode($node){
      if($node->getLTag() == 1){
        return $node->getLeft();
      }else{
        return $this->getLastThreadNode($node->getLeft());
      }
    }
    //返回某个结点的后继
    public function getNextNode($node){
      if($node->getRTag() == 1){
        return $node->getRight();
      }else{
        return $this->getFirstThreadNode($node->getRight());
      }
    }
    //返回中序线索二叉树的第一个结点
    public function getFirstThreadNode($node){
      while($node->getLTag() == 0){
        $node = $node->getLeft();
      }
      return $node;
    }
    //返回中序线索二叉树的最后一个结点
    public function getLastThreadNode($node){
      while($node->getRTag() == 0){
        $node = $node->getRight();
      }
      return $node;
    }
    //前序遍历
    private function frontList($node, & $nodeList){
      if($node !== NULL){
        $nodeList[] = $node->getData();
        $this->frontList($node->getLeft(), $nodeList);
        $this->frontList($node->getRight(), $nodeList);
      }
    }
    //中序遍历
    private function middleList($node, & $nodeList){
      if($node != NULL){
        $this->middleList($node->getLeft(), $nodeList);
        $nodeList[] = $node->getData();
        $this->middleList($node->getRight(), $nodeList);
      }
    }
    //后序遍历
    private function lastList($node, & $nodeList){
      if($node != NULL){
        $this->lastList($node->getLeft(), $nodeList);
        $this->lastList($node->getRight(), $nodeList);
        $nodeList[] = $node->getData();
      }
    }
    public function getData(){
      return $this->data;
    }
    public function getRoot(){
      return $this->root;
    }
  }
?>

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP数据结构与算法教程》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php操作office文档技巧总结(包括word,excel,access,ppt)》、《php日期与时间用法总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家PHP程序设计有所帮助。

相关文章

  • php实现简单文件下载的方法

    php实现简单文件下载的方法

    这篇文章主要介绍了php实现简单文件下载的方法,以实例形式简单分析了文件下载的原理与实现技巧,非常简单实用,需要的朋友可以参考下
    2015-01-01
  • PHP源码之explode使用说明

    PHP源码之explode使用说明

    最近一直在想有关字符串操作的一些效率上的事情,截取字串的问题,都会避免不了重新分配空间的消耗,也顺带看了explode这个函数的源码,理解下,拿出自己的分析共享下
    2011-08-08
  • php合并数组中相同元素的方法

    php合并数组中相同元素的方法

    这篇文章主要介绍了php合并数组中相同元素的方法,通过一个自定义函数遍历数组实现数组中相同项的合并,是非常实用的技巧,需要的朋友可以参考下
    2014-11-11
  • PHP字符串中特殊符号的过滤方法介绍

    PHP字符串中特殊符号的过滤方法介绍

    本篇文章主要是对PHP字符串中特殊符号的过滤方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-02-02
  • PHP imagecreatefrombmp 从BMP文件或URL新建一图像

    PHP imagecreatefrombmp 从BMP文件或URL新建一图像

    大家都知道php GD库可方便的从URL新建一图像, GD中有imagecreatefromjpeg(),imagecreatefromPNG()....等
    2012-07-07
  • php获取当前月与上个月月初及月末时间戳的方法

    php获取当前月与上个月月初及月末时间戳的方法

    这篇文章主要介绍了php获取当前月与上个月月初及月末时间戳的方法,涉及php针对日期与时间相关判断与操作技巧,需要的朋友可以参考下
    2016-12-12
  • php magic_quotes_gpc的一点认识与分析

    php magic_quotes_gpc的一点认识与分析

    最近一直在做一个文章发布系统,做了改,改了做,一直到现在还没竣工.... 为了达到更好的兼容性,其中的程序涉及到了magic_quotes_gpc,看了下手册,又找了些资料,分析了下,分享给大家。
    2008-08-08
  • PHP伪静态写法附代码

    PHP伪静态写法附代码

    PHP伪静态写法 伪静态又名:URL重写 主要是为了SEO而生的。(SEO是什么?这个不用问我吧。呵呵~搞网络的不懂SEO那就~~~~)
    2008-06-06
  • PHP 使用MySQL管理Session的回调函数详解

    PHP 使用MySQL管理Session的回调函数详解

    本篇文章文章是对PHP中使用MySQL管理Session的回调函数进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • PHP面向对象程序设计OOP继承用法入门示例

    PHP面向对象程序设计OOP继承用法入门示例

    这篇文章主要介绍了PHP面向对象程序设计OOP继承用法,结合简单实例形式分析了php类的定义与继承使用方法,需要的朋友可以参考下
    2016-12-12

最新评论