使用php实现的无限极的树结构

<?php




/**
 * 无限的等级树
 * @author chzcb
 * @email chzcb2008@gmail.com
 */
class inf_node
{
	/**
	 *  索引 递归增长
	 * @var int
	 */
	public $index;
	public $childrens;


	public $id;
	public $pid;
	public $level;
	public $parent;
	public $name;
	public $data;


	public function __construct($name,$id=0,$pid=0,$data=NULL)
	{
		$this->id = $id;
		$this->pid = $pid;
		$this->level = 0;
		$this->name = $name;
		$this->data = $data;
		$this->childrens = array();
	}


	/**
	 * 设置索引号
	 * @param $index int
	 */
	protected function setIndex($index)
	{
		$this->index = $index;
	}
	/**
	 * 获取索引号
	 */
	protected function getIndex()
	{
		return $this->index;
	}
	/**
	 * 添加子节点
	 * @param $node inf_node
	 */
	public function addChild($node)
	{
		if($this->childrens !== null)
		{
			$node->setIndex(count($this->childrens));
			array_push($this->childrens,$node);
			$node->parent = $this;
			$node->setLevel($this->level+1);
		}
	}


	/**
	 * 设置某一个节点
	 * @param $node inf_node
	 * @param $index int
	 */
	public function setChildAt($node,$index)
	{
		$index = $this->removeChild($node);
		if($index!==false)
		{
			if($node->getIndex()<$index)
			{
				$this->addChildAt($node,$index-1);
			}
			else
			{
				$this->addChildAt($node,$index);
			}
		}
		return $index;
	}


	/**
	 * 插入node到特定位置
	 * @param $node inf_node
	 * @param $index int 如果index 超出范围,自动自增到最大。
	 */
	public function addChildAt($node,$index)
	{
		if($this->childrens !== null)
		{
			$is_insert = false;
			if($index<0)
				$index = count($this->childrens)+$index;


			$pre_childs = array_slice($this->childrens,0,$index);
			$suffix_childs = array_slice($this->childrens,$index,count($this->childrens)-$index);


			if(count($suffix_childs)>0)
			{
				$node->setIndex($index);
				foreach ($suffix_childs as $n)
				{
					$n->setIndex($n->getIndex()+1);
				}
				$this->childrens = array_merge($pre_childs,array($node),$suffix_childs);
			}
			else
			{
				$this->addChild($node);
				return;
			}
			$node->parent = $this;
			$node->setLevel($this->level+1);
		}
	}


	/**
	 * 删除当前节点
	 * @param $node inf_node
	 */
	public function removeChild($node)
	{
		$index = array_search($node,$this->childrens);
		if($index !== false)
		{
			$this->removeChildAt($index);
		}
		return $index;
	}


	/**
	 * 删除当前节点下第index个子节点。
	 * @param $index int
	 */
	public function removeChildAt($index)
	{
		$pre_childs = array_slice($this->childrens,0,$index);
		$suffix_childs = array_slice($this->childrens,$index+1,count($this->childrens)-$index-1);
		if(count($suffix_childs)>0)
		{
			foreach ($suffix_childs as $node)
			{
				$node->setIndex($node->getIndex()-1);
			}
		}
		array_splice($this->childrens,$index,1);


		return $this->childrens;
	}


	/**
	 * 设置当前节点以及其子节点的所有目录级别
	 * @param $level int
	 */
	public function setLevel($level)
	{
		$has_child = true;
		$this->level = $level;
		while($has_child)
		{
			$has_child = false;
			if(count($this->childrens)>0)
			{
				foreach($this->childrens as $node)
				{
					$t_has_child = $node->setLevel($level+1);
					if($t_has_child)
					{
						$has_child = true;
					}
				}
			}
		}
		return $has_child;
	}
	/**
	 * 通过id获得节点
	 * @param $id int
	 */
	public function getNodeById($id)
	{
		if($this->id == $id)
		{
			return $this;
		}
		$is_find = false;
		if(count($this->childrens)>0)
		{
			foreach($this->childrens as $node)
			{
				$is_find = $node->getNodeById($id);
				if($is_find!=false)
					break;
			}
		}
		return $is_find;
	}
	
	/**
	 * 刷新树
	 */
	public function flush()
	{
	    if(count($this->childrens)>0)
    	{
        	foreach($this->childrens as $node)
        	{
        		$pnode = $this->getNodeById($node->pid);
        		if($pnode == $node)
        		{
        		    continue;
        		}
        		if($pnode != false)
        		{
        		    $this->removeChild($node);
        		    $pnode->addChild($node);
        		}
        		$node->flush();
        	}
    	}
	}
	
	public function toXML()
	{
		
	}


	/**
	 * 测试输出
	 */
	public function view()
	{
		$has_child = true;
		echo '<li>',$this->level,'.',$this->getIndex(),'   ',$this->name,' id:',$this->id,' pid:',$this->pid,'</li>';
		while($has_child)
		{
			$has_child = false;
			if(count($this->childrens)>0)
			{
				echo '<ul>';
				foreach($this->childrens as $node)
				{
					$t_has_child = $node->view();
					if($t_has_child)
					{
						$has_child = true;
					}
				}
				echo '</ul>';
			}
		}
		return $has_child;
	}
}
/*
$list = array(
	array('id'=>1,'name'=>'食品','parent'=>0),
	array('id'=>2,'name'=>'水果','parent'=>1),
	array('id'=>3,'name'=>'蔬菜','parent'=>1),
	array('id'=>4,'name'=>'桃子','parent'=>2),
	array('id'=>5,'name'=>'西瓜','parent'=>2),
	array('id'=>6,'name'=>'香蕉','parent'=>3),
	array('id'=>7,'name'=>'芹菜','parent'=>3),
	array('id'=>8,'name'=>'白菜','parent'=>3),
	array('id'=>9,'name'=>'青菜','parent'=>3),
	array('id'=>10,'name'=>'萝卜','parent'=>3),
	array('id'=>11,'name'=>'牛肉','parent'=>15),
	array('id'=>12,'name'=>'羊肉','parent'=>15),
	array('id'=>13,'name'=>'猪肉','parent'=>15),
	array('id'=>15,'name'=>'肉类','parent'=>1),
);
$tree = new inf_node('root');
shuffle($list);
foreach($list as $obj)
{
	$tnode = new inf_node($obj['name'],$obj['id'],$obj['parent']);
	$pnode = $tree->getNodeById($obj['parent']);
	if($pnode!=false)
	{
		$pnode->addChild($tnode);
	}
	else
	{
		$tree->addChild($tnode);
	}
}
$tree->view();
$tree->flush();
$tree->view();*/
贴上一个php写的无限极树,嘿嘿,大家帮忙看看
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值