[php]
/**
* 無限レベル (末尾ノード記述アルゴリズムによって制限されます。詳細については、tree_parse コメントを参照してください) 再帰メニュー
* 著者: selfimpr
*ブログ:http://blog.csdn.net/lgg201
*メール: lgg860911@yahoo.com.cn
*/
define('MAX_NODES', 3); /* 子ノードの最大数 */
define('MAX_NODE_INDEX', MAX_NODES - 1); /* 子ノードの最大インデックス値 */
define('NAME_FMT', 'name-%08d'); /* ノード内容の出力形式文字列 */
/* ツリーノードのデータ構造 */
定義('K_ID', 'id');
定義('K_NAME', '名前');
定義('K_CHILD', '子供');
/* 構築に使用されるアセンブリ文字を出力します */
define( 'prefix_top'、ass
define('PREFIX_BOTTOM', '┗'); /* 各親ノードの最後の子ノードの識別子 */
define('PREFIX_MIDDLE', '┠'); /* 上記 2 つの状況に該当しないすべてのノードの識別子 */
定義 ('prefix_line', '┇');
定義 ('スペース', ''); / * 空白の位置 (すべての末尾ノードはコネクタを表示しません) * /
define('WIDE_SPACE', str_repeat(SPACE, 4)); /* ツリーの階層を明確にするための広い空白のプレースホルダー */
/**
* データビルド
* ノードを構築します
* @param 混合 $id ノード ID
* @parammixed $is_leaf 葉っぱかどうか
* @アクセス公開
* @return void
*/
関数node_build($id, $is_leaf = FALSE) {
配列を返します(
K_ID => $id、
K_NAME => sprintf(NAME_FMT, $id)、
K_CHILD => $is_leaf ? : array(),
);
}
/**
* ツリービルド
* ツリーを構築します (ツリー内の各ノードの子ノードの数は MAX_NODES によって決まります)
* @parammixed $datas 返されるツリー参照
* @parammixed $id 開始ID
* @parammixed $level ツリーのレベル
* @アクセス公開
* @return void
*/
関数tree_build(&$datas, &$id, $level) {
( $level
$data = node_build($id ++, $is_leaf);
if ( !$is_leaf )
Tree_build($data[K_CHILD], $id, $next_level);
array_push($datas, $data);
}
}
/**
* ノード文字列
* ノード自身の情報を出力します
* @parammixed $string 結果の文字列を返します(値渡し)
* @param 混合 $data ノードデータ
* @アクセス公開
* @return void
*/
関数node_str(&$string, $data) {
$string .= sprintf(' %s[%d]', $data[K_NAME], $data[K_ID]);
}
/**
* ノードサイン
* ノードのグリフを出力します
* @parammixed $string 結果の文字列を返します(値渡し)
* @parammixed $level 現在の深さ
* @parammixed $i 親ノード内の現在のノードのインデックス(添え字)
* @アクセス公開
* @return void
*/
関数node_sign(&$string, $level, $i) {
スイッチ ( $i ) {
ケース 0:
$string .= $level == 0 ? PREFIX_TOP : PREFIX_MIDDLE;
休憩
ケース MAX_NODE_INDEX:
$string .= PREFIX_BOTTOM;
休憩
デフォルト:
$string .= PREFIX_MIDDLE;
休憩
}
}
/**
* ノードプレフィックス
* ノードのプレフィックスを出力します
* @parammixed $string 結果の文字列を返します(値渡し)
* @parammixed $level 現在の深さ
* @parammixed $is_last 現在のノードのすべての祖先ノード (含む) に末尾ノード マークがあるかどうか
* @アクセス公開
* @return void
*/
関数ノードプレフィックス(&$string, $level, $is_last) {
If ( $level > 0 ) {
$i = 0;
/* プレフィックス形式: "親接続" ["ワイド ホワイトスペース" "親接続" ...] "ワイド ホワイトスペース" */
$string .= ($is_last & 1 << ($level - $i) ? SPACE : PREFIX_LINE);
ながら (++ $i < $level)
$string .= WIDE_SPACE . ($is_last & 1 << ($level - $i) ? SPACE : PREFIX_LINE);
$string .= WIDE_SPACE;
}
}
/**
* ノードアウト
* ノードを出力します
* @parammixed $string 結果の文字列を返します(値渡し)
* @parammixed $data 処理対象のノードデータ
* @param 混合 $level ノードの深さ
* @parammixed $i 親ノード内のノードのインデックス(添え字)
* @parammixed $is_last 現在のノードのすべての祖先ノード (含む) に末尾ノード マークがあるかどうか
* @アクセス公開
* @return void
*/
関数node_out(&$string, $data, $level, $i, $is_last) {
/* プレフィックス文字列の処理: 祖先コネクタと空白 */
Node_prefix($string, $level, $is_last);
/* このノードの識別子を処理します */
Node_sign($string, $level, $i);
/* このノードのデータ情報を処理します */
ノードstr($string, $data);
/*改行を追加 */
$string .= "n";
}
/**
* ツリー_パース
* ツリーを出力します
* 1. 整数 $is_last は祖先が末尾ノードであるかどうかのマークとして使用されるため、PHP_INT_MAX の深さまでサポートします
※2. 拡張が必要な場合は、$is_lastのデータ型と検証方法を変更するだけです
* @parammixed $string 結果の文字列を返します(値渡し)
* @parammixed $datas 処理対象のツリーデータ
* @param int $level 現在の処理の深さ
* @param int $is_last 現在の深さのすべての先祖が末尾ノードでマークされているかどうか
* @アクセス公開
* @return void
*/
関数tree_parse(&$string, $datas, $level = 0, $is_last = 0) {
If ( !is_array($datas) || count($datas) < 1 ) return ;
$max_index = count($datas) - 1;
/* このレイヤー内のすべてのノードを処理します */
foreach ( $datas as $i => $data ) {
/* 現在のノードとすべての祖先が末尾ノードとしてマークされているかどうか */
$ tmp_is_last
/* 現在のノードを出力します */
Node_out($string, $data, $level, $i, $tmp_is_last);
/* 子ノードがある場合は、子ノードを再帰します */
If ( is_array($data[K_CHILD]) && !emptyempty($data[K_CHILD]) )
Tree_parse($string, $data[K_CHILD], $level + 1, $tmp_is_last);
}
}
/* 実際のノード数を計算します */
関数 n_node($n, $s) {
$sum = 0;
while ( $n > 0 )
$ sum
$sum を返します。
}
/* ルアージュ時間を計算します */
関数 ru_time($info, $type) {
floatval(sprintf('%d.%d', $info[$type . '.tv_sec'], $info[$type . '.tv_usec']));
}
/* リソース使用量を出力します */
関数 resource_usage($lv, $nodes, $cb, $ce, $mb, $me, $rb, $re) {
printf("nリソース使用量[レベル: %d、ノード番号: %d]: n%20s%0.6fsn%20s%0.6fsn%20s%0.6fsn%20s%d バイト",
$lv、$nodes、
'時刻: ', $ce - $cb,
'システム CPU: ', ru_time($re, 'ru_stime') - ru_time($rb, 'ru_stime'),
'ユーザー CPU: ', ru_time($re, 'ru_utime') - ru_time($rb, 'ru_utime'),
'メモリ使用量: ', $me - $mb);
}
/* 使用法 */
関数の使用法($cmd) {
Printf("使用法: n%s n", $cmd);
出る
}
/* テストエントリー関数 */
関数 run() {
グローバル $argc、$argv
If ( $argc != 2 || intval($argv[1])
使用法($argv[0]);
$datas = 配列();
$id = 1;
$string = '';
$level = intval($argv[1]);
/* テストツリーの初期構築 */
Tree_build($datas, $id, $level);
$ Clock_begin = マイクロタイム (TRUE);
$memory_begin = メモリ_get_usage();
$rusage_begin = ゲトルセージ();
/* 解析ツリー */
Tree_parse($string, $datas);
$rusage_end = getrusage();
$memory_end = メモリ_get_usage();
$クロック_エンド = マイクロタイム(TRUE);
/* 結果を出力します */
エコー $string
Resource_usage($level, n_node($level, MAX_NODES),
$時計_開始、$時計_終了、
$memory_begin、$memory_end、
$rusage_begin、$rusage_end);
}
/* エントリ関数を実行 */
実行();
/*
* ローカル変数:
*タブ幅: 4
* c-basic-offset: 4
* インデントタブモード: t
*終わり:
*/