PHP实现的线索二叉树及二叉树遍历方法详解
来源: 阅读:1292 次 日期:2016-08-26 14:36:27
温馨提示: 小编为您整理了“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程序设计有所帮助。

更多信息请查看 网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2026上岸·考公考编培训报班

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们| 联系我们| 人才招聘| 网站声明| 网站帮助| 非正式的简要咨询| 简要咨询须知| 新媒体/短视频平台| 手机站点| 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65099533/13759567129 获取招聘考试信息及咨询关注公众号:
咨询QQ:1093837350(9:00—18:00) 版权所有:
云南网警报警专用图标
Baidu
map