Version: 0.2
Type: Full Script
Category: Algorithms
License: GNU General Public License
Description: This is a simple implementation of a Tree structure using matrix Queue representation. Functions for adding elements and listing the tree. I used it for a directory tree implementation.
<?php //Simple Tree v0.1 //This is a simple implementation of a Tree structure using matrix Queue representation. //Author:Mircea Banu ([email protected]) //02.02.2004 /* Simple Tree v0.2 added additional comments for the tree_add function, added a looping function that will find orphaned chilren and add them to the branch Added a sorting function to sort the items in a list alphabetically Added a dynamic tree view, will only show the current branching, will not remember which nodes are open Save the file as simple_tree_view_02.php Author: Ken Foubert ([email protected]) 2004-5-27 */ global $tree; $id = 6; if ( isset($_GET['id']) ) $id = $_GET['id']; $p=new Nod("root",0,0); $root=$p; tree_add($p); $arrCat = create_category_array('baseball'); //loop through each array and it to the tree foreach ( $arrCat AS $arrDetail ) { $p = new Nod($arrDetail['name'], $arrDetail['cat_id'], $arrDetail['parent_id']); tree_add($p); } //end forech ###################################################################################################################### ###################################################################################################################### ###################################################################################################################### ?> <html> <body> <?php //tree_list(); //print_r( $tree ); //echo "<hr>"; $tree = sort_tree( $tree ); //echo "<br>"; tree_list(); //echo "<br>"; create_tree_view( $tree, $id ); ?> </body> </html> </body> </html> <? ###################################################################################################################### ###################################################################################################################### ###################################################################################################################### function tree_add($to_add) { //Ads a new element into the tree global $tree; $i=0; $j=0; //loop through all the existing branches while($tree[$i][0]!=NULL) { $j=0; //if $to_add father id matches the first element id, //then place $to_element in the branch as the last element if($tree[$i][0]->get_id()==$to_add->get_father()) { while($tree[$i][$j]!=NULL) { $j++; } //end while $tree[$i][$j-1]->set_last_child(0); $tree[$i][$j]=$to_add; } //end if $i++; } //end while //create a new branch $tree[$i][0]=$to_add; $branch = 0; //exit if at athe root level if ( $tree[$i][0]->get_id() == 0 && $tree[$i][0]->get_father() == 0 ) { return 0; } //end if //loop through all the existing branches and find any orphaned children while($tree[$branch][0]!=NULL) { //the new position starts after the last element $new_element_pos = count( $tree[$i] ); //if $to_add id matches the first element father id of the branch, //then add that element as a child to the $to_add node if($tree[$i][0]->get_id()==$tree[$branch][0]->get_father()) { //the previous item is no longer the last child if ( $tree[$i][$new_element_pos - 1] != NULL ) { $tree[$i][$new_element_pos - 1]->set_last_child(0); } $tree[$i][$new_element_pos] = $tree[$branch][0]; $tree[$i][$new_element_pos]->set_last_child(1); } //end if $branch++; } //end while } //end function function sort_tree( $tree ) { foreach ( $tree as $key=>$branch ) { $branch = sort_array( $branch ); $tree[$key] = $branch; } //end foreach return $tree; } //end function //Sorts a branch of the tree alphabetically function sort_array( $branch ) { $array_size = count( $branch ); $hold = array(); //don't sort the first element, which is the parent //use a bubble sort for ( $pass = 1; $pass < $array_size - 1; $pass++ ) { for ( $current = 1; $current < $array_size - 1; $current++ ) { /* echo "branch[current]: ".$branch[$current]->get_name()."<br>"; echo "branch[current+1]: ".$branch[$current+1]->get_name()."<br>"; echo "<hr>"; */ if ( strcmp($branch[$current]->get_name(), $branch[$current + 1]->get_name()) > 0 ) { //set the last_child to 0 for all of them $branch[$current]->set_last_child(0); $branch[$current + 1]->set_last_child(0); $hold = $branch[$current]; $branch[$current] = $branch[$current + 1]; $branch[$current + 1] = $hold; /* echo "<b>Hold</b><br>"; print_r( $hold ); echo "<br>current<br>"; print_r( $branch[$current]); echo "<br>current + 1<br>"; print_r( $branch[$current + 1]); echo "<br>result<br>"; print_r( $branch ); echo "<br>"; */ } //end if } //end for } //end for loop //set last_child to 1 for last_element $branch[$array_size -1]->set_last_child(1); /* echo "<br>set last child<br>"; print_r( $branch ); echo "<br>"; */ return $branch; } //end function function tree_list() { //List the tree global $tree; $i=0; while($tree[$i][0]!=NULL) { $j=0; while($tree[$i][$j]!=NULL) { echo "(".$tree[$i][$j]->get_id().")".$tree[$i][$j]->get_id().' => '.$tree[$i][$j]->get_name().' p='.$tree[$i][$j]->get_father(); $j++; } //end while $i++; echo "<br>"; } //end while } //end function function tree_height($p) { //Returns the tree height global $tree; $i=0; $gata=0; if($p->get_id()==0) { return 0; } //end if else { while(($tree[$i][0]!=NULL)and($gata!=1)) { $j=1; while(($tree[$i][$j]!=NULL)and($gata!=1)) { if($tree[$i][$j]->get_id()==$p->get_id()) { $gata=1; } //end if $j++; } //end while $i++; } //end while if($tree[$i-1][0]->get_id()!=0) { return 1+tree_height($tree[$i-1][0]); } //end if else { return 1; } //end else } //end else } //end function function tree_has_children($p) { //Returns true if the tree has children global $tree; $i=0; while($tree[$i][0]->get_id()!=$p->get_id()) { $i++; } //end while if($tree[$i][1]!=NULL) { return 1; } //end if else { return 0; } //end else } //end function function create_category_array($type='baseball') { if( $type == 'rand' ) { $i=1; $arrCat = array(); while($i < 10) { $i_name = "node_".$i; $i_id = $i; $i_parent = rand(0,$i); $arrCat[] = array( "cat_id"=>$i_id, "parent_id"=>$i_parent, "name"=>$i_name); $i++; } //end while } elseif( $type == 'baseball' ) { $arrCat = array ( array( "cat_id"=>"1", "parent_id"=>0, "name"=>"National League"), array( "cat_id"=>"2", "parent_id"=>1, "name"=>"NL West"), array( "cat_id"=>"4", "parent_id"=>1, "name"=>"NL Central"), array( "cat_id"=>"14", "parent_id"=>40, "name"=>"AL Central"), array( "cat_id"=>"16", "parent_id"=>40, "name"=>"AL East"), array( "cat_id"=>"22", "parent_id"=>12, "name"=>"Seattle"), array( "cat_id"=>"20", "parent_id"=>12, "name"=>"Texas"), array( "cat_id"=>"33", "parent_id"=>14, "name"=>"Minnesota"), array( "cat_id"=>"27", "parent_id"=>14, "name"=>"Detroit"), array( "cat_id"=>"25", "parent_id"=>16, "name"=>"Baltimore"), array( "cat_id"=>"6", "parent_id"=>1, "name"=>"NL East"), array( "cat_id"=>"3", "parent_id"=>2, "name"=>"Los Angeles"), array( "cat_id"=>"5", "parent_id"=>2, "name"=>"San Francisco"), array( "cat_id"=>"7", "parent_id"=>4, "name"=>"Houston"), array( "cat_id"=>"13", "parent_id"=>4, "name"=>"Pittsburgh"), array( "cat_id"=>"15", "parent_id"=>6, "name"=>"Montreal"), array( "cat_id"=>"17", "parent_id"=>6, "name"=>"Atlanta"), array( "cat_id"=>"40", "parent_id"=>0, "name"=>"American League"), array( "cat_id"=>"12", "parent_id"=>40, "name"=>"AL West"), array( "cat_id"=>"19", "parent_id"=>16, "name"=>"Toronto") ); } elseif( $type == 'db_table' ) { ini_set( 'max_execution_time', '60' ); $connect = mysql_connect( 'www.test.com', 'tree_view', 'password' ); if( !$connect ){ die("Unable to make connection!"); } $db = mysql_select_db('nce'); if(!$db){ die("Problem choosing database!"); } $sql = 'SELECT c.id, c.name, c.parent_id FROM categories c WHERE c.active = "Y" '; $res = mysql_query($sql) or die(mysql_error()); while($i = mysql_fetch_assoc($res)) { $i_name = $i['name']; $i_id = $i['id']; $i_parent = $i['parent_id']; $arrCat[] = array( "cat_id"=>$i_id, "parent_id"=>$i_parent, "name"=>$i_name); $i++; } } return $arrCat; } //end function //================================================================================================================ //create a tree based on the id function create_tree_view( &$tree, &$id ) { ?> <p><a href="simple_tree_view_02.php?id=0">Home</a></p> <? $arrLevel = array(); $arrLevel = get_branches( $tree, $id ); //start at the last element, which is always the root level $level = count( $arrLevel ) - 1; //this function uses recursion print_level( $arrLevel, $level ); } //end function //get the branches based on the selected id function get_branches( &$tree, &$id ) { $arrLevel = array(); $end_search = ""; $level = 0; $selected_id = 0; $selected_id = $id; //loop until all the branches have been found while ( $end_search <> "end" ) { //loop through each $branch in the $tree array foreach ( $tree AS $branch ) { //check the first object in the branch //if the selected_id matches the id of first element, then get that branch if ( $selected_id == $branch[0]->get_id() ) { $arrLevel[$level] = $branch; //get the father id of the first element. This will determine //the next branch to grab. $selected_id = $branch[0]->get_father(); $level = $level + 1; //if the root level has been found, then quit if ( $branch[0]->get_id() == 0 && $branch[0]->get_father() == 0 ) { $end_search = "end"; } //end if //no reason to keep looping, quit the foreach continue; } //end if } //end foreach } //end while return $arrLevel; } //end function function print_level( &$arrLevel, $level ) { echo "<ul>n"; //loop through each child for ( $child = 1; $child < count($arrLevel[$level]); $child++ ) { $child_id = $arrLevel[$level][$child]->get_id(); $tree_url = "<a href="simple_tree_view_02.php?id=$child_id">"; echo "<li>$tree_url".$arrLevel[$level][$child]->get_name()."</a></li>"; //make sure the next level has children if ( count($arrLevel[$level-1]) > 1) { //if the next level contains the child, then print that level if ( $arrLevel[$level][$child]->get_id() == $arrLevel[$level-1][0]->get_id() ) { print_level($arrLevel, $level-1); } //end if } //end if } //end for loop echo "</ul>n"; } //end function //================================================================================================================ class Nod { //the class containing the tree element properties and some functions var $name; var $id; var $father; var $last_child;//1 is the last child added, 0 else function Nod($name,$id,$father_id) { //constructor $this->name=$name; $this->id=$id; $this->father=$father_id; $this->last_child=1; } //end function function get_name() { return $this->name; } //end function function get_id() { return $this->id; } //end function function get_father() { return $this->father; } //end function function last_child() { return $this->last_child; } //end function function set_last_child($val) { $this->last_child=$val; } //end function } //end class ?>