问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

请教高手:php实现n叉树遍历

发布网友 发布时间:2022-04-06 04:47

我来回答

2个回答

热心网友 时间:2022-04-06 06:16

  要构建的无限分类的模型. 电子产品是最大的分类.家用电器 ,数码产品是其子分类.可以看到子分类是被父分类包含起来的.每个分类都有左右 两个节点编号分别是1、2、3.....

  根据上面的图mysql中建立表和插入数据

  CREATE TABLE  `proct_categories` (

  `id` MEDIUMINT( 8 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,`name` VARCHAR( 20 ) NOT NULL ,

  `left_node` MEDIUMINT( 8 ) NOT NULL ,

  `right_node` MEDIUMINT( 8 ) NOT NULL

  ) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;INSERT INTO `proct_categories` (`id`, `name`, `left_node`, `right_node`) VALUES(1, '电子产品', 1, 20),

  (2, '家用电器', 2, 9),

  (3, '电视机', 3, 4),

  (4, '电冰箱', 5, 6),

  (5, '空调', 7, 8),

  (6, '数码产品', 10, 19),

  (7, '电脑', 11, 18),

  (8, '台式电脑', 12, 13),

  (9, '笔记本电脑', 14, 15),

  (10, '平板电脑', 16, 17);

  表结构如下:

  下面是PHP的实例代码:

  1、获取所有节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT c.name FROM proct_categories as c, proct_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='电子产品' ORDER BY c.left_node");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  foreach($rs as $v){

  echo $v['name'].'<br />';

  }

  输出:

  电子产品

  家用电器

  电视机

  电冰箱

  空调

  数码产品

  电脑

  台式电脑

  笔记本电脑

  平板电脑

  2、 获取某个父节点以及其所有子节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT c.name FROM proct_categories as c, proct_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='数码产品' ORDER BY c.left_node");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  foreach($rs as $v){

  echo $v['name'].'<br />';

  }

  输出:

  数码产品

  电脑

  台式电脑

  笔记本电脑

  平板电脑

  3、获取所有的叶子节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT name FROM proct_categories where right_node-left_node=1");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  foreach($rs as $v){

  echo $v['name'].'<br />';

  }

  输出:

  电视机

  电冰箱

  空调

  台式电脑

  笔记本电脑

  平板电脑

  4、获取某个子节点及其所有父节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT p.name FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node AND c.name = '平板电脑' ORDER BY p.left_node");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  foreach($rs as $v){

  echo $v['name'].'<br />';

  }

  输出:

  电子产品

  数码产品

  电脑

  平板电脑

  5、获取所有节点极其所处的层级

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node GROUP BY c.name ORDER BY c.left_node");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  var_mp($rs);

  echo '<br />';

  foreach($rs as $v){

  echo $v['name'].' level:'.$v['level'].'<br />';}

  输出:

  电子产品 level:0

  家用电器 level:1

  电视机 level:2

  电冰箱 level:2

  空调 level:2

  数码产品 level:2

  电脑 level:2

  台式电脑 level:3

  笔记本电脑 level:3

  平板电脑 level:3

  6、获取某个节点的层级

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  $stmt = $pdo->prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node and c.name='平板电脑' GROUP BY c.name ORDER BY c.left_node");$stmt->execute();

  $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);

  var_mp($rs);

  echo '<br />';

  foreach($rs as $v){

  echo $v['name'].' level:'.$v['level'].'<br />';}

  输出:

  平板电脑 level:3

  7、在某个节点后平行的插入一个节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  function addNode($left_node,$new_node){

  global $pdo;

  $stmt = $pdo->prepare("SELECT right_node FROM proct_categories WHERE name = '$left_node'");$stmt->execute();

  $rs=$stmt->fetch(PDO::FETCH_ASSOC);

  $right_node=$rs['right_node'];

  $pdo->exec("UPDATE proct_categories SET right_node = right_node + 2 WHERE right_node > $right_node");$pdo->exec("UPDATE proct_categories SET left_node = left_node + 2 WHERE left_node > $right_node");$pdo->exec("INSERT INTO proct_categories(name, left_node, right_node) VALUES('$new_node', $right_node + 1, $right_node + 2)");}

  addNode('家用电器','办公用品');

  完成之后表结构如下:

  8、删除某个节点及其所有子节点

  <?php

  $pdo = new PDO(

  'mysql:host=localhost;dbname=test',

  'root',

  ''

  );

  $pdo->exec("SET NAMES UTF8");

  function deleteNode($node_name){

  global $pdo;

  $stmt = $pdo->prepare("SELECT left_node,right_node, right_node - left_node + 1 as width FROM proct_categories WHERE name ='$node_name'");$stmt->execute();

  $rs=$stmt->fetch(PDO::FETCH_ASSOC);

  $left_node=$rs['left_node'];

  $right_node=$rs['right_node'];

  $width=$rs['width'];

  $pdo->exec("DELETE FROM proct_categories WHERE left_node BETWEEN $left_node AND $right_node");$pdo->exec("UPDATE proct_categories SET right_node = right_node - $width WHERE right_node > $right_node");$pdo->exec("UPDATE proct_categories SET left_node = left_node - $width WHERE left_node > $right_node");}

  deleteNode('数码产品');

  完成之后表结构如下:

  可以看到用多叉树的方式构建无限分类,查询的时候是非常简便的.但是在插入新的节点和删除节点时就比较麻烦了.

热心网友 时间:2022-04-06 07:34

树状图?还是放射线的那种,你倒是截个图说明白点啊
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎么才能让孩子感知到父母的爱? ...准备入手一个 努比亚(nubia)小牛4 Z9mini 全黑 努比亚(nubia)小牛4 z9mini 怎么样 同样的价格,努比亚z9 mini和小米4该买哪台? 魅蓝ntoe电信吧和努比亚Z9 mini 怎么选择 请问性生活之前要注意什么卫生…之后又注意些什么卫生啊… 更改win10电脑系统语言win10电脑怎么将系统语言换成中文 win10电脑语言设置win10如何更改系统语言 Win10电脑改成英文如何将Win10中文版系统改为英文版 windows10中文版怎么改英语 win10中文版系统怎么改成英文版 php无限级分类表的建立问题 PHP无限树形根统计数据 php无限分类怎么弄 大神请进:如何用PHP和MySQL实现无限分类相册 PHP无限级分类 PHP无限级分类怎么查询 php无限级分类ul li如何格式输出? PHP+MySQL无限分类语句 php+mysql怎么实现无限级别分类,数据库怎么设计?一条SQL语句读出数据然后生成数组 discuz怎么设置阿里云oss远程附件 oss阿里云怎么设置自动上传文件 阿里云oss 上传及访问问题 上传图片到阿里云的OSS上,可以吗 怎么上传图片到阿里云? 文件上传问题。PHP些的云存储服务器,调用平台接口上传文件(例如阿里云等)。 求助阿里云服务器上传图片代码php版本 PHP如何使用阿里云oss 阿里云oss php上传图片问题 上传前把图片重命名之后再上传到oss 怎么写代码呢 Php调用手机发短信功能 好做么?PHP短信接口开发 php mysql数据库查询语句并输出 PHP MYSQL 查询 汇总数据并输出到页面。 PHP输出mysql查询! php+mysql 做树形可折叠二级菜单怎么做?超高分啊!求助!!! php已经查询到mysql里的数据 如何输出? PHP如何通过传引用的思想实现无限分类(代码 PHP无限级分组算法问题 急求PHP递归无限分类,当前位置写法 php递归无限分类缩进怎么做?? 急啊 php递归实现无极分类的一个问题 在laravel框架里面实现php前台无限分类怎么遍历数据 J2EE于PHP的比较? 参加培训,去培训javaee还是PHP好 话说javaee在开发网站比php有什么优势 php和java有什么区别,我会点php学java是不是很容易上手 tp5框架index.php入口文件隐藏? thinkphp怎么隐藏入口文件 为什么要隐藏index.php入口文件 thinkphp站点下怎么隐藏前台和后台的入口文件index.php,admin.php 使分页的时候url不会出错! thinkphp站点下怎么隐藏前台和后台的入口文件index.php,admin.php 使分页的时候url不错