<?php
/**
* Chained processing units (tree structure)
* @author Ionut Bodea
*/
/*
* Tree Nodes (adiacent list)
*/
$aNodes = array(
1 => array(2, 3),
3 => array(4, 5, 6),
5 => array(7, 8)
);
$oTree = new Core_DataStructure_Tree($aNodes);
echo 'Tree (recursive, multi level array):';
print_r($oTree->getTree());
echo 'Tree (horizontal representation):';
print_r($oTree->getTreeHorizontal());
class Core_DataStructure_Tree
{
private $adiacentList;
private $tree = array();
## private $isTree = false;
public function __construct($adiacentList)
{
$this->adiacentList = $adiacentList;
$this->computeTree();
}
private function computeTree()
{
$this->tree = array();
foreach($this->adiacentList as $sParent => $aChildren)
{
if(empty($aChildren))
{
$this->addNode($sParent);
}
else
{
foreach($aChildren as $sChild)
{
$this->addNode($sParent, $sChild);
}
}
}
}
private function addNode($sParent, $sChild = null)
{
## echo 'Add node - parent: '.$sParent.', child: '.$sChild.'<br/>';
if(!$this->nodeExists($sParent))
{
$this->tree[] = array(
'node' => $sParent,
'children' => array()
);
}
if(null === $sChild)
{
return;
}
if($this->nodeExists($sChild))
{
## move existing child under a new parent (move an entire branch under a new parent)
## echo 'node exists: [[[[' . $sChild . ']]]]';
$aXpathResult = $this->getNodeXPath($sParent);
$aXPathParent = $aXpathResult['xPath'];
$aXpathResult = $this->getNodeXPath($sChild);
$aXPathChild = $aXpathResult['xPath'];
$sVarParent = "\$this->tree[".implode('][\'children\'][', $aXPathParent)."]";
$sVarChild = "\$this->tree[".implode('][\'children\'][', $aXPathChild)."]";
$sStringEval = "$sVarParent" . "['children'][] = $sVarChild;";
eval($sStringEval);
$sStringEval = "unset($sVarChild);";
eval($sStringEval);
}
else
{
$aXpathResult = $this->getNodeXPath($sParent);
$aXPath = $aXpathResult['xPath'];
$aEntry = array('node' => $sChild, 'children' => array());
## printr($aEntry);
$sStringEval = "\$this->tree[".implode('][\'children\'][', $aXPath)."]['children'][] = \$aEntry;";
eval($sStringEval);
}
## printr($this->tree);
## echo '<hr/>';
}
private function nodeExists($sNode, $aNodes = null)
{
$aNodes = null === $aNodes ? $this->tree : $aNodes;
foreach($aNodes as $aNode)
{
if(isset($aNode['node']) && $aNode['node'] == $sNode)
{
return true;
}
if(isset($aNode['children']) && !empty($aNode['children']))
{
return $this->nodeExists($sNode, $aNode['children']);
}
}
return false;
}
private function getNodeXPath($sNode, $aNodes = null, $aXPath = array())
{
## printr($this->tree);
$aNodes = null === $aNodes ? $this->tree : $aNodes;
foreach($aNodes as $k => $aNode)
{
if(isset($aNode['node']) && $aNode['node'] == $sNode)
{
$aXPath[] = $k;
return array('nodeFound' => true, 'xPath' => $aXPath);
## return $aXPath;
}
if(isset($aNode['children']) && !empty($aNode['children']))
{
## $aXPath[] = $k;
## $aResult = $this->getNodeXPath($sNode, $aNode['children'], $aXPath);
$aResult = $this->getNodeXPath($sNode, $aNode['children'], array_merge($aXPath, array($k)));
if(isset($aResult['nodeFound']) && $aResult['nodeFound'])
{
return $aResult;
}
## return $this->getNodeXPath($sNode, $aNode['children'], array_merge($aXPath, array($k)));
}
}
return array('nodeFound' => false, 'xPath' => $aXPath);
}
/* public function isTree()
{
return $this->isTree;
} */
/**
* @return array
*/
public function getTree()
{
return $this->tree;
}
/**
* Get a horizontal representation of the tree
* Array
* [] -> level 0 nodes
* [] -> level 1 nodes
* ....
* @return array
*/
public function getTreeHorizontal($aNodes = null, $nLevel = null, &$aResults = array())
{
$aNodes = null === $aNodes ? $this->tree : $aNodes;
$nLevel = null === $nLevel ? 0 : $nLevel + 1;
foreach($aNodes as $aNode)
{
!isset($aResults[$nLevel]) ? $aResults[$nLevel] = array() : '';
$aResults[$nLevel][] = $aNode['node'];
$this->getTreeHorizontal($aNode['children'], $nLevel, $aResults);
}
return $aResults;
}
}
/**
* Chained processing units (tree structure)
* @author Ionut Bodea
*/
/*
* Tree Nodes (adiacent list)
*/
$aNodes = array(
1 => array(2, 3),
3 => array(4, 5, 6),
5 => array(7, 8)
);
$oTree = new Core_DataStructure_Tree($aNodes);
echo 'Tree (recursive, multi level array):';
print_r($oTree->getTree());
echo 'Tree (horizontal representation):';
print_r($oTree->getTreeHorizontal());
class Core_DataStructure_Tree
{
private $adiacentList;
private $tree = array();
## private $isTree = false;
public function __construct($adiacentList)
{
$this->adiacentList = $adiacentList;
$this->computeTree();
}
private function computeTree()
{
$this->tree = array();
foreach($this->adiacentList as $sParent => $aChildren)
{
if(empty($aChildren))
{
$this->addNode($sParent);
}
else
{
foreach($aChildren as $sChild)
{
$this->addNode($sParent, $sChild);
}
}
}
}
private function addNode($sParent, $sChild = null)
{
## echo 'Add node - parent: '.$sParent.', child: '.$sChild.'<br/>';
if(!$this->nodeExists($sParent))
{
$this->tree[] = array(
'node' => $sParent,
'children' => array()
);
}
if(null === $sChild)
{
return;
}
if($this->nodeExists($sChild))
{
## move existing child under a new parent (move an entire branch under a new parent)
## echo 'node exists: [[[[' . $sChild . ']]]]';
$aXpathResult = $this->getNodeXPath($sParent);
$aXPathParent = $aXpathResult['xPath'];
$aXpathResult = $this->getNodeXPath($sChild);
$aXPathChild = $aXpathResult['xPath'];
$sVarParent = "\$this->tree[".implode('][\'children\'][', $aXPathParent)."]";
$sVarChild = "\$this->tree[".implode('][\'children\'][', $aXPathChild)."]";
$sStringEval = "$sVarParent" . "['children'][] = $sVarChild;";
eval($sStringEval);
$sStringEval = "unset($sVarChild);";
eval($sStringEval);
}
else
{
$aXpathResult = $this->getNodeXPath($sParent);
$aXPath = $aXpathResult['xPath'];
$aEntry = array('node' => $sChild, 'children' => array());
## printr($aEntry);
$sStringEval = "\$this->tree[".implode('][\'children\'][', $aXPath)."]['children'][] = \$aEntry;";
eval($sStringEval);
}
## printr($this->tree);
## echo '<hr/>';
}
private function nodeExists($sNode, $aNodes = null)
{
$aNodes = null === $aNodes ? $this->tree : $aNodes;
foreach($aNodes as $aNode)
{
if(isset($aNode['node']) && $aNode['node'] == $sNode)
{
return true;
}
if(isset($aNode['children']) && !empty($aNode['children']))
{
return $this->nodeExists($sNode, $aNode['children']);
}
}
return false;
}
private function getNodeXPath($sNode, $aNodes = null, $aXPath = array())
{
## printr($this->tree);
$aNodes = null === $aNodes ? $this->tree : $aNodes;
foreach($aNodes as $k => $aNode)
{
if(isset($aNode['node']) && $aNode['node'] == $sNode)
{
$aXPath[] = $k;
return array('nodeFound' => true, 'xPath' => $aXPath);
## return $aXPath;
}
if(isset($aNode['children']) && !empty($aNode['children']))
{
## $aXPath[] = $k;
## $aResult = $this->getNodeXPath($sNode, $aNode['children'], $aXPath);
$aResult = $this->getNodeXPath($sNode, $aNode['children'], array_merge($aXPath, array($k)));
if(isset($aResult['nodeFound']) && $aResult['nodeFound'])
{
return $aResult;
}
## return $this->getNodeXPath($sNode, $aNode['children'], array_merge($aXPath, array($k)));
}
}
return array('nodeFound' => false, 'xPath' => $aXPath);
}
/* public function isTree()
{
return $this->isTree;
} */
/**
* @return array
*/
public function getTree()
{
return $this->tree;
}
/**
* Get a horizontal representation of the tree
* Array
* [] -> level 0 nodes
* [] -> level 1 nodes
* ....
* @return array
*/
public function getTreeHorizontal($aNodes = null, $nLevel = null, &$aResults = array())
{
$aNodes = null === $aNodes ? $this->tree : $aNodes;
$nLevel = null === $nLevel ? 0 : $nLevel + 1;
foreach($aNodes as $aNode)
{
!isset($aResults[$nLevel]) ? $aResults[$nLevel] = array() : '';
$aResults[$nLevel][] = $aNode['node'];
$this->getTreeHorizontal($aNode['children'], $nLevel, $aResults);
}
return $aResults;
}
}