[PHP]
/**
* Infinite level (limited by tail node description algorithm, see tree_parse Note) Recursive menu
* AUTHOR:SELFIMPR
* blog:http://blog.csdn.net/lgg201
* mail:lgg860911@yahoo.com.cn
*/
Define (' Max_nodes ', 3); /* Maximum number of child nodes */
Define (' Max_node_index ', max_nodes-1); /* child node Maximum index value */
Define (' name_fmt ', ' name-%08d '); /* node content output format string */
/* Tree node data structure */
Define (' k_id ', ' ID ');
Define (' K_name ', ' NAME ');
Define (' K_child ', ' children ');
/* Assembled characters used when the output is constructed */
Define (' Prefix_top ', ' ┏ '); /* Identifier of first node of first layer */
Define (' Prefix_bottom ', ' ┗ '); /* The identifier of the last child node of each parent node */
Define (' Prefix_middle ', ' ┠ '); /* Identifier of all nodes not in the above two cases */
Define (' Prefix_line ', ' ┇ '); /* line character for ancestor node */
Define (' SPACE ', '); /* Blank placeholder (all tail nodes do not show line characters) */
Define (' Wide_space ', Str_repeat (SPACE, 4)); /* Wide blank placeholder, in order to make the tree level clear */
/**
* Data_build
* Construction of a node
* @param mixed $id Node ID
* @param mixed $is _leaf whether leaves
* @access Public
* @return void
*/
function Node_build ($id, $is _leaf = FALSE) {
Return Array (
k_id = $id,
K_name = sprintf (name_fmt, $id),
K_child = $is _leaf? Null:array (),
);
}
/**
* Tree_build
* Construct a tree (the number of child nodes per node in the tree is determined by max_nodes)
* @param mixed $datas The tree reference to return
* @param mixed $id start ID
* @param the level of the mixed $level tree
* @access Public
* @return void
*/
Function Tree_build (& $datas, & $id, $level) {
if ($level < 1) return;
$is _leaf = $level = = 1;
$i =-1;
$next _level = $level-1;
while (+ + $i < Max_nodes) {
$data = Node_build ($id + +, $is _leaf);
if (! $is _leaf)
Tree_build ($data [K_child], $id, $next _level);
Array_push ($datas, $data);
}
}
/**
* NODE_STR
* Output information of one node itself
* @param mixed $string String that returns the result (reference pass value)
* @param mixed $data node data
* @access Public
* @return void
*/
Function Node_str (& $string, $data) {
$string. = sprintf ('%s[%d] ', $data [K_name], $data [k_id]);
}
/**
* Node_sign
* Output a node glyph
* @param mixed $string String that returns the result (reference pass value)
* @param mixed $level Current depth
* @param mixed $i The index of the current node in the parent node (subscript)
* @access Public
* @return void
*/
Function Node_sign (& $string, $level, $i) {
Switch ($i) {
Case 0:
$string. = $level = = 0? Prefix_top:prefix_middle;
Break
Case Max_node_index:
$string. = Prefix_bottom;
Break
Default
$string. = Prefix_middle;
Break
}
}
/**
* Node_prefix
* Output prefix of one node
* @param mixed $string String that returns the result (reference pass value)
* @param mixed $level Current depth
* @param mixed $is _last the current node (including) whether the tail node tag of all ancestor nodes
* @access Public
* @return void
*/
Function Node_prefix (& $string, $level, $is _last) {
if ($level > 0) {
$i = 0;
/* Prefix format: "Parent lines" ["Wide Whitespace" "Parent line" ...] "Wide white space character" */
$string. = ($is _last & 1 << ($level-$i)? Space:prefix_line);
while (+ + $i < $level)
$string. = Wide_space. ($is _last & 1 << ($level-$i)? Space:prefix_line);
$string. = Wide_space;
}
}
/**
* Node_out
* Output of one node
* @param mixed $string String that returns the result (reference pass value)
* @param mixed $data The node data to be processed
* @param mixed $level node depth
* @param the index of the mixed $i node in the parent node (subscript)
* @param mixed $is _last the current node (including) whether the tail node tag of all ancestor nodes
* @access Public
* @return void
*/
Function Node_out (& $string, $data, $level, $i, $is _last) {
/* Handle prefix String: Ancestor's connector and blank */
Node_prefix ($string, $level, $is _last);
/* Handle the identity symbol for this node */
Node_sign ($string, $level, $i);
/* Process This node data information */
Node_str ($string, $data);
/* Append line break */
$string. = "\ n";
}
/**
* Tree_parse
* Output a tree
* 1. The depth of the Php_int_max is supported because the integer $is_last is used as the ancestor's mark of the tail node
* 2. If you need to expand, fix the $is_last data type and verify the method
* @param mixed $string String that returns the result (reference pass value)
* @param mixed $datas The tree data to be processed
* @param int $level The depth of the current processing
* @param int $is _last Current Depth all ancestors whether tail node mark
* @access Public
* @return void
*/
Function Tree_parse (& $string, $datas, $level = 0, $is _last = 0) {
if (!is_array ($datas) | | count ($DATAS) < 1) return;
$max _index = count ($datas)-1;
/* Handle all nodes of this layer */
foreach ($datas as $i = = $data) {
/* The current node and all ancestors are marked with a tail node */
$tmp _is_last = $is _last << 1 | 1 & $i = = $max _index;
/* Output Current node */
Node_out ($string, $data, $level, $i, $tmp _is_last);
/* If there are child nodes, recursive child nodes */
if (Is_array ($data [k_child]) &&!emptyempty ($data [K_child])
Tree_parse ($string, $data [K_child], $level + 1, $tmp _is_last);
}
}
/* Calculate the actual number of nodes */
function N_node ($n, $s) {
$sum = 0;
while ($n > 0)
$sum + = Pow ($s, $n-);
return $sum;
}
/* Calculate ruage Time */
function Ru_time ($info, $type) {
Return Floatval (sprintf ('%d.%d ', $info [$type. '. Tv_sec '], $info [$type. '. Tv_usec ']);
}
/* Output Resource Usage */
function Resource_usage ($LV, $nodes, $CB, $ce, $MB, $me, $RB, $re) {
printf ("\nresource usage[level:%d, node number:%d]: \n%20s%0.6fs\n%20s%0.6fs\n%20s%0.6fs\n%20s%d byte\n",
$LV, $nodes,
' Clock time: ', $ce-$CB,
' System CPU: ', Ru_time ($re, ' ru_stime ')-Ru_time ($RB, ' ru_stime '),
' User cpu: ', Ru_time ($re, ' ru_utime ')-Ru_time ($RB, ' ru_utime '),
' Memory usage: ', $me-$MB);
}
/* Usage */
function usage ($cmd) {
printf ("Usage: \n%s \ n ", $cmd);
Exit
}
/* Test Entry function */
function Run () {
Global $ARGC, $ARGV;
if ($ARGC! = 2 | | intval ($ARGV [1]) < 1)
Usage ($argv [0]);
$datas = Array ();
$id = 1;
$string = ";
$level = Intval ($argv [1]);
/* Initial Construction Test tree */
Tree_build ($datas, $id, $level);
$clock _begin = Microtime (TRUE);
$memory _begin = Memory_get_usage ();
$rusage _begin = Getrusage ();
/* Parse tree */
Tree_parse ($string, $datas);
$rusage _end = Getrusage ();
$memory _end = Memory_get_usage ();
$clock _end = Microtime (TRUE);
/* Output Results */
Echo $string. "\ n";
Resource_usage ($level, N_node ($level, Max_nodes),
$clock _begin, $clock _end,
$memory _begin, $memory _end,
$rusage _begin, $rusage _end);
}
/* Execute the entry function */
Run ();
/*
* Local variables:
* Tab-width:4
* C-basic-offset:4
* Indent-tabs-mode:t
* End:
*/
http://www.bkjia.com/PHPjc/477981.html www.bkjia.com true http://www.bkjia.com/PHPjc/477981.html techarticle PHP/** * Infinite level (limited by tail node description algorithm, see tree_parse Note) Recursive menu * AUTHOR:SELFIMPR * blog:http://blog.csdn.net/lgg201 * MAIL:LG g860911@yahoo.com.cn ...