PHP实现的线索二叉树及二叉树遍历方法详解
作者:z32556601 发布时间:2023-11-13 11:28:06
标签: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程序设计有所帮助。


猜你喜欢
- 什么是事件委托/事件代理利用事件的冒泡传播机制(触发当前元素的某一个行为,它父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要
- 写给新手的话pycharm是什么,为什么让我指定interpreter记事本最开始写C语言代码的时候,人们使用vi,记事本等软件写代码,写完
- md5是一种常见不可逆加密算法,使用简单,计算速度快,在很多场景下都会用到,比如:给用户上传的文件命名,数据库中保存的用户密码,下载文件后检
- Pytest和Unittest测试框架的区别?如何区分这两者,很简单unittest作为官方的测试框架,在测试方面更加基础,并且可以再次基础
- 本文实例讲述了Python构建XML树结构的方法。分享给大家供大家参考,具体如下:1.构建XML元素#encoding=utf-8from
- 某些杀毒软件会把正常的asp文件误认为是asp木马文件,而自动删除,影响正常使用。下面方法可能会有效避免被杀毒软件删除把dim t
- 1.Fork出来的Git仓库同步代码背景:有的时候从原仓库fork出了一个新仓库,这个新仓库做了自己的修改。可是原仓库也进行了更新,比如修复
- python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件。1、得到
- 看着自己少得可怜的访问量,突然有一个想用爬虫刷访问量的想法,主要也是抱着尝试的心态,学习学习。其实市面上有一些软件可以代刷流量 比如 流量精
- pickle 是一个 python 中, 压缩/保存/提取 文件的模块,字典和列表都是能被保存的.但必须注意的是python2以ASCII形
- 一。初识单元测试1)定义:单元:函数或者是类单元测试:测试类或者函数python内置的单元测试框架:unittest2)单元测试的意义好处:
- 一.需求统计收集各个实例上table的信息,主要是表的记录数及大小。收集的范围是cmdb中所有的数据库实例。二.公共基础文件说明1.配置文件
- 近期对数据库进行巡检,发现数据库业务用户(非 SYS/Public)下存在失效对象。对失效对象进行分析,主要包括失效的视图、物化视图、函数、
- 当代码已经写得差不多,发现某个变量名需要修改,但代码中很多地方都有该变量,一一修改太麻烦了,在不同的情景下,可以采取更加简便的方法,如下介绍
- 上篇文章给大家介绍了 在 webpack 中使用 ECharts的实例详解 ,可以点击查看。1. 使用NPM安装(全局引入)执行下面的命令:
- **截止文章发布chinese_calendar版本为1.8.0,大约在每年的11月份更新次年的节假日新版本import datetimef
- My Sql 大部分都是用绿色版(解压版) 然后注册服务 简单方便。但是。配置文件头痛的一逼。首先配置mysql的环境变量。mySQL 环境
- var yData = [];//Y轴数据 var xData = [];//X轴数据 $(data.rows).each(function
- SELECT sch.name + '.' + t.name AS [Table Name],
- 本文实例讲述了python实现堆栈与队列的方法。分享给大家供大家参考。具体分析如下:1、python实现堆栈,可先将Stack类写入文件st