设为首页 收藏本站
查看: 473|回复: 0

[经验分享] PHP实现二叉树,线索二叉树

[复制链接]

尚未签到

发表于 2017-4-9 11:49:32 | 显示全部楼层 |阅读模式
<?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(empty($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;
}
}
?>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362379-1-1.html 上篇帖子: 网站性能-cgi fastcgi mod_php相关概念整理 下篇帖子: PHP无限分类的例子(包括数据库)转
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表