Re: Figuring out tree depth.

From: Date: Fri, 28 Sep 2001 02:23:43 +0000
Subject: Re: Figuring out tree depth.
References: 1  Groups: php.general 
Request: Send a blank email to php-general+get-69083@lists.php.net to get a copy of this message
Give this a shot: foreach ($roots as $node) { getChildren($node, 0); echo "<br><br>"; } function getChildren($current, $depth ){ global $children; echo "$depth -- $current[1]<br>"; $count = count($children); for($i = 0; $i < $count; $i++){ if($children[$i][2] == $current[0]){ getChildren($children[$i], $depth + 1); } } } -- Justin Garrett "Kris Williams" <ahrt@enternet.com.au> wrote in message news:5.1.0.14.0.20010927165139.00b1ad88@mail.enternet.com.au... > Hiyas, > > I've made the following script to build a tree style navigation from a > table of sections for an image gallery. There are root nodes of the tree > which can have children, and those children can have their own children and > so on to an infinte depth. A root node has a parentID of 0 and a child node > has a parentID of the row id you want the child to belong to. (I've faked > the arrays that would be returned from MySQL for this example). > > The script is rendering items in the correct order, but I can't keep track > of how deep in the tree each item is so I can indent them properly. A root > node should have a 0 depth, it's child should have 1, and it's child again > should be 2, then the next child of the root should go back to 1. It seems > to be working right until it gets to "rusted" (see eg). > > I can figure that I'm adding items to the lastNode array but not removing > them properly nor am I decrementing $x which is what should be keeping > partial track of how deep I am. I figure this is where I'm going wrong but > can't for the life of me figure it out. The calling of huntChild within > itself is killing me. > > The script at the moment is: > > <? > // Results have to be ordered by parentID (3rd field) > $roots = array(); > $roots[0] = array("1","skatey","0"); > $roots[1] = array("4","me","0"); > $roots[2] = array("5","friends","0"); > > $children = array(); > $children[0] = array("2","parks","1"); > $children[1] = array("10","equipment","1"); > $children[2] = array("3","regular visits","2"); > $children[3] = array("7","regular stacks","2"); > $children[4] = array("12","regular zzz","2"); > $children[5] = array("14","concrete","3"); > $children[6] = array("15","metal","3"); > $children[7] = array("6","0-10 years old","4"); > $children[8] = array("8","10-20 years old","4"); > $children[9] = array("11","blood spills","7"); > $children[10] = array("13","guts everywhere","7"); > $children[11] = array("9","skeg phase","8"); > $children[12] = array("16","chipped","14"); > $children[13] = array("17","rusted","15"); > > $lastNode = array(); > > // Make sure the tree depth is set to 0, then hammer through the roots > array, pull out the next root node and go check if it has any children. > foreach ($roots as $key) { > $depth = 0; > echo "<br><b>" . $depth . " - " . $key[1] . > "</b><br>"; > $lastNode = array(); > array_unshift($lastNode,$key[0]); > huntChildren($children,$key[0]); > } > > function huntChildren($childArray,$rootID) { > global $depth; > global $lastNode; > $x = 0; > > for ($i = 0; $i < sizeof($childArray); $i++) { > // Suck out the first child node into a new array. > $tmpChild = array_shift($childArray); > > // Check to see if the parentID in $tmpChild matches the id of the node > passed ($rootID) when the function is called. > // A match means that the child has the node as a parent. > if ($rootID == $tmpChild[2]) { > if ($lastNode[0] != $tmpChild[2]) { > $x++; > array_unshift($lastNode,$tmpChild[2]); > } > > if ($x > 1) { > $depth = sizeof($lastNode) - $x; > } else { > $depth = sizeof($lastNode); > } > > echo $depth . " - " . $tmpChild[1] . "<br>"; > > // Go see if this child has children. > huntChildren($childArray,$tmpChild[0]); > } else { > // If there are no children to the node passed, put $tmpChild array > back into the passed array of children for the next iteration. > array_push($childArray,$tmpChild); > } > } > } > ?> > > and should generate: > > 0 - skatey > 1 - parks > 2 - regular visits > 3 - concrete > 4 - chipped > 3 - metal > 4 - rusted > 2 - regular stacks > 3 - blood spills > 3 - guts everywhere > 2 - regular zzz > 1 - equipment > > 0 - me > 1 - 0-10 years old > 1 - 10-20 years old > 2 - skeg phase > > 0 - friends > > > Aside from the depth problem the script functions just the way I want it > to, but if anyone wants to point out or fix any major problems as well as > my depth one, it'd be much appreciated. > > Apologies for any shoddy indenting and the massive post. Trying to give as > much info as I can. > > Thanks, > Kris. >

« previous php.general (#69083) next »