Infinite pole classification is often used in development, for example: Department structure, article classification. The difficulty with infinite pole classification is "output" and "query", for example
- Output the category of the article as a <ul> list form;
- Find the articles that are included in all categories under Category A.
1. Principle of implementation
This article introduces several common methods of realizing the idea of infinite class classification, and has advantages and disadvantages. "Improved pre-sequence traversal tree" data structure, easy to output and query, but in the mobile classification and general understanding is somewhat complex.
2. Data structure 0
ID |
FID |
title |
1 |
China |
2 |
1 |
Jiangsu |
3 |
1 |
Anhui |
4 |
8 |
jiangyin |
5 |
3 |
Wuhu |
6 |
3 |
Hefei |
7 |
3 |
Bengbu |
8 |
2 |
Wuxi |
<?php $list = array( array(‘id‘=>1, ‘fid‘=>0, ‘title‘ => ‘中国‘), array(‘id‘=>2, ‘fid‘=>1, ‘title‘ => ‘江苏‘), array(‘id‘=>3, ‘fid‘=>1, ‘title‘ => ‘安徽‘), array(‘id‘=>4, ‘fid‘=>8, ‘title‘ => ‘江阴‘), array(‘id‘=>5, ‘fid‘=>3, ‘title‘ => ‘芜湖‘), array(‘id‘=>6, ‘fid‘=>3, ‘title‘ => ‘合肥‘), array(‘id‘=>7, ‘fid‘=>3, ‘title‘ => ‘蚌埠‘), array(‘id‘=>8, ‘fid‘=>8, ‘title‘ => ‘无锡‘) );?>
A classification tree is formed by the level "concatenation" between the categories through the parent class ID (FID). It is worth noting in tandem that the FID of categorical a cannot be the ID of its subclass.
In the use of this data structure to output the most commonly used algorithm is "recursive", familiar with the PHP language friends must know that PHP is not good at recursion, and the number of recursion is limited (about 100 times, due to operating system and configuration vary).
Since all recursion can be implemented using loops, a function of "infinite Class" classification is written according to PHP language features, which is more efficient than recursive implementations.
3. Output UL List form
Export the above data to the following HTML
<ul> <li class="first-child"> <div>江苏</div> <ul> <li class="first-child last-child"> <div>无锡</div> <ul> <li class="first-child last-child"> <div>江阴</div> </li> </ul> </li> </ul> </li> <li class="last-child"> <div>安徽</div> <ul> <li class="first-child"><div>芜湖</div></li> <li><div>合肥</div></li> <li class="last-child"><div>蚌埠</div></li> </ul> </li></ul>
This HTML structure is handy for front-end use (using JavaScript and CSS to construct collapsible trees). The specific implementation procedure is as follows:
<ul><?php get_tree_ul($list, 1); ?></ul>
4. Output Option List form
<select><option value="2">江苏</option><option value="8"> 无锡</option><option value="4"> 江阴</option><option value="3">安徽</option><option value="5"> 芜湖</option><option value="6"> 合肥</option><option value="7"> 蚌埠</option></select>
The specific implementation procedure is as follows:
<select><?php // get_tree_option()返回数组,并为每个元素增加了“深度”(即depth)列,直接输出即可 $options = get_tree_option($list, 1); foreach($options as $op) { echo ‘<option value="‘ . $op[‘id‘] .‘">‘ . str_repeat(" ", $op[‘depth‘] * 4) . $op[‘title‘] . ‘<;/option>‘; }?><;/select>
5. Find all subclasses of a class
<?php $children = get_tree_child($list, 0); echo implode(‘,‘, $children); // 输出:1,3,2,7,6,5,8,4?>
6. Find all the parent classes for a category
<?php $children = get_tree_parent($list, 4); echo implode(‘,‘, $children); //8, 2, 10?>
7. Related functions
<?phpfunction Get_tree_child ($data, $fid) {$result = array (); $fids = Array ($FID); do {$cids = array (); $flag = false; foreach ($fids as $fid) {for ($i = count ($data)-1; $i >=0; $i-) {$node = $data [$i]; if ($node [' fid '] = = $fid) {array_splice ($data, $i, 1); $result [] = $node [' id ']; $cids [] = $node [' id ']; $flag = true; }}} $fids = $cids; } while ($flag = = = True); return $result;} function Get_tree_parent ($data, $id) {$result = array (); $obj = Array (); foreach ($data as $node) {$obj [$node [' id ']] = $node; } $value = Isset ($obj [$id])? $obj [$id]: null; while ($value) {$id = null; foreach ($data as $node) {if ($node [' id '] = = $value [' FID ']) {$id = $node [' id ']; $result [] = $node [' id ']; BReak; }} if ($id = = = null) {$result [] = $value [' FID ']; } $value = Isset ($obj [$id])? $obj [$id]: null; } unset ($obj); return $result;} function Get_tree_ul ($data, $fid) {$stack = array ($FID); $child = Array (); $added _left = Array (); $added _right= Array (); $html _left = Array (); $html _right = Array (); $obj = Array (); $loop = 0; foreach ($data as $node) {$pid = $node [' FID ']; if (!isset ($child [$pid])) {$child [$pid] = array (); } array_push ($child [$pid], $node [' id ']); $obj [$node [' id ']] = $node; } while (count ($stack) > 0) {$id = $stack [0]; $flag = false; $node = Isset ($obj [$id])? $obj [$id]: null; if (Isset ($child [$id])) {$cids = $child [$id]; $length = count ($cids); for ($i = $length-1; $i >= 0; $i-) {Array_unshift ($stack, $cids [$i]); } $obj [$cids [$length -1]][' islastchild '] = true; $obj [$cids [0]][' isfirstchild '] = true; $flag = true; if ($id! = $fid && $node &&!isset ($added _left[$id]) {if (Isset ($node [' Isfirstchild '] ) && isset ($node [' islastchild ']) {$html _left[] = ' <li class= ' first-child last-child ' > '; } else if (Isset ($node [' Isfirstchild ')]) {$html _left[] = ' <li class= ' first-child ' > '; } else if (Isset ($node [' Islastchild ')]) {$html _left[] = ' <li class= ' last-child ' > '; } else {$html _left[] = ' <li> '; } $html _left[] = ($flag = = = True)? "<div>{$node [' title ']}</div><ul> ': ' <div>{$node [' title ']}</div> '; $added _left[$id] = true; if ($id! = $fid && $node &&!isset ($added _right[$id])) {$html _right[] = ($flag == = True)? ' </ul></li> ': ' </li> '; $added _right[$id] = true; if ($flag = = False) {if ($node) {$cids = $child [$node [' FID ']]; for ($i = count ($cids)-1; $i >= 0; $i-) {if ($cids [$i] = = $id) {array_sp Lice ($child [$node [' FID '], $i, 1); Break }} if (count ($child [$node [' fid ']] = = 0) {$child [$node [' fid ']] = null; }} array_push ($html _left, Array_pop ($html _right)); Array_shift ($stack); } $loop + +; if ($loop >) return $html _left; } unset ($child); Unset ($obj); Return implode (", $html _left);} function Get_tree_option ($data, $fid) {$stack = array ($FID); $child = Array (); $added = Array (); $options = Array (); $obj = Array (); $loop = 0; $depth =-1; foreach ($data As $node) {$pid = $node [' FID ']; if (!isset ($child [$pid])) {$child [$pid] = array (); } array_push ($child [$pid], $node [' id ']); $obj [$node [' id ']] = $node; } while (count ($stack) > 0) {$id = $stack [0]; $flag = false; $node = Isset ($obj [$id])? $obj [$id]: null; if (Isset ($child [$id])) {for ($i = count ($child [$id])-1; $i >= 0; $i-) {Array_unshift ($st Ack, $child [$id] [$i]); } $flag = true; if ($id! = $fid && $node &&!isset ($added [$id])) {$node [' depth '] = $depth; $options [] = $node; $added [$id] = true; } if ($flag = = True) {$depth + +; } else {if ($node) {for ($i = count ($child [$node [' FID ']])-1; $i >= 0; $i-) { if ($child [$node [' FID ']][$i] = = $id) {array_splice ($child [$node [' FID ']],$i, 1); Break }} if (count ($child [$node [' fid ']] = = 0) {$child [$node [' fid ']] = null; $depth--; }} array_shift ($stack); } $loop + +; if ($loop >) return $options; } unset ($child); Unset ($obj); return $options;}? >