预排序遍历树算法小结

作者: AduGEN | 来源:发表于2016-07-19 19:09 被阅读2073次

       前几天在项目开发中遇到了前辈们所设计的结构(用来实现商品分类),所设计的结构便是利用了预排序遍历树算法。故特此去查询资料以便掌握该知识点!下面是我这些天的心得体会。

一,商品分类表--建表语句和数据库结构

CREATE  TABLE IF NOT EXISTS `test`.`product_type` (
    `pt_id` INT(11) unsigned NOT NULL AUTO_INCREMENT ,
    `pt_name` varchar(50) NOT NULL COMMENT '分类名称' ,
    `pt_fid` INT(11) unsigned NOT NULL DEFAULT 0 COMMENT '父分类id' ,
    `pt_depth` tinyint(5) NOT NULL DEFAULT 0 COMMENT '分类深度' ,
    `pt_left` INT(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点左侧编号' ,
    `pt_right` INT(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点右侧编号' ,
    PRIMARY KEY (`pt_id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci
COMMENT = '商品分类表';

商品分类表数据结构 .jpg

建表成功后的数据结构

二,预排序遍历树的结构

1.jpg

      当我第一眼看到这个图的时候,我的最大的疑问就是图1.jpg上的那些节点的左右数字编号是如何确定的?为什么B节点的左右编号是2和11?E,F这些节点的左右编号相差1?
      首先我们用手指按照图中红线箭头所示的方向自行描一遍,分别从1赋值到20,明白了没有?(还不明白,那就再描一遍)。从根节点的左侧向下(平行结构时从左到右)数字加1,如:B C D 节点所组成的树。到此,我们可以看出来每个终端节点的左右编号相差为1;一个节点的左编号必定是以该节点为根节点所组成树的编号里面的最小值,而它的右编号必定是最大值,这样才能涵盖它子孙节点的编号变化。

三,所对应的相关算法

      插入数据,将图1.jpg所显示的结构存入数据库中(我们一条条的添加),这样有助于我们更加清晰直观的了解整个树结构的变化。在见到整个结构之前你是不知道1.jpg所示结构的,那么我们按照业务逻辑来的话,商品分类逐级建立,则sql语句应如下:
      //添加一级分类 A
      insert into product_type(pt_name,pt_fid,pt_depth,pt_left,pt_right) values('A',0,1,1,2);
      //A下添加二级分类B  (A的主键已知)
      select * from product_type where pt_id=1;              //得到A的左右编号 1 2 
      select max(pt_right) from product_type where pt_fid = 1;    //得 null ,故A没有子节点
      update product_type set pt_right = pt_right+2 where  pt_right>=2;  //A右编号+2 为B腾出空间
      insert into product_type(pt_name,pt_fid,pt_depth,pt_left,pt_right) values('B',1,2,2,3);
      //B下添加三级分类C (B的主键已知)
      select * from product_type where pt_id=2;              //得到B的左右编号  2 3
      select max(pt_right) from product_type where pt_fid = 2;    //得 null ,故B没有子节点
      update product_type set pt_right = pt_right+2 where  pt_right>=3;  //A,B右编号+2 为C腾出空间 
      insert into product_type(pt_name,pt_fid,pt_depth,pt_left,pt_right) values('C',2,3,3,4);
      //B下添加三级分类D(B的主键已知)
     select * from product_type where pt_id=2;              //得到B的左右编号  2 3
     select max(pt_right) from product_type where pt_fid = 2;    //得 4 ,故D左右为 5 6
     update product_type set pt_right = pt_right+2 where  pt_right > 4;  //A,B右编号+2 为D腾出空间
     insert into product_type(pt_name,pt_fid,pt_depth,pt_left,pt_right) values('D',2,3,5,6);
     ......(好烦,为了页面好看在此省略下面的代码)

     建立好结构后,我们可以很清楚的发现一些规律:

    1. 那我们在查询数据库时where条件为 pt_right - pt_left = 1 的所查询出来的结构必定为终端节点。sql语句如下 :
        select * from product_type where pt_right - pt_left = 1;
    2. 得到某个节点下面的所有子孙节点,只需要where条件 pt_left 大于该节点的左值 and pt_right小于该节点的右值,以b节点举例,则sql语句如下:
        select * from product_type where pt_left>2 and pt_right<11 order by pt_left asc;
        得到的结果是 C,D,E,F四个节点的数据。
    3. 查找两个节点之间的路径,以A到E为例,sql语句如下:
        select * from product_type where pt_left between 1 and 6 and pt_right between 7 and 20 order by pt_left ;
        得到的结果是A,B,D,E 这4个节点的数据。
    4.通过我们刚才新增数据得到这个结构的操作,我们发现新增分两种情况。第一种如下图所示:

新增节点X

变更所有的受影响的节点,给新节点腾出空位子,所有左节点比G节点大的,都增加2,所有右节点比G节点大的,也都增加2,则sql语句如下:
      update product_type set pt_left=pt_left+2 where pt_left>12;
      update product_type set pt_right=pt_right+2 where pt_right>13;
另一种为新增子节点,但该新增的节点左侧并有节点。举例:在E下新增Y节点,Y节点左右值为7,8,这时我们在修改后续节点时也应该考虑到E节点的存在。所以sql语句如下:
      update product_type set pt_left=pt_left+2 where pt_left>6;      

      update product_type set pt_right=pt_right+2 where pt_right>=7;

算法说明:

1.所有分类 左边和右边的值 > 插入节点的左边节点记录的右值 的全部 + 2
2.插入节点 左值 = 插入位置左边节点记录的右值 + 1, 右值 = 插入位置左边节点记录的右值 + 2

总结:

      经过这几天的相关操作和查询资料,整理后我写出了这些东西,但我的收获远不止这些,奈何语言水平有限就讲这么多吧!

相关文章

  • 预排序遍历树算法小结

    前几天在项目开发中遇到了前辈们所设计的结构(用来实现商品分类),所设计的结构便是利用了预排序遍历树算法。故特...

  • 算法之预排序遍历树算法

    在我们需要快速查询后代或者祖先的需求中,预排序遍历树算法就显示了出来 预排序遍历树算法顾名思义其实在数据落地之前就...

  • 预排序遍历数算法

    转的地址忘了,如有侵权请@ 预排序遍历树算法 现在让我们看一看另外一种不使用递归计算,更加快速的方法,这就是预排序...

  • 预排序遍历树

    什么是左右值无限级分类左右值无限级分类,也称为预排序树无限级分类,是一种有序的树状结构,位于这些树状结构中的每一个...

  • 面试题

    面试题 二叉树 非递归实现二叉树遍历 节点: 前序遍历 中序遍历 后序遍历 排序 快速排序 其他问题 算法题 给一...

  • 2020前端面试(数据结构)

    常见排序算法 冒泡排序 快速排序 选择排序 插入排序 数组扁平化 递归 reduce toString 树的遍历 ...

  • 数据结构必备代码

    目录: 排序算法 树的遍历 查找 链表插入 数组与列表转化 二维数组排序 java中输入 集合遍历 一、基本排序1...

  • 数据结构与算法目录

    操作系统目录 哈希树遍历链表数组排序堆与栈队列高级算法

  • 图的桥和割点

    内容概要: 图中的桥 图的DFS遍历树和BFS遍历树及其与寻桥算法的关系 图的割点 DFS和BFS的对比小结 桥(...

  • MySQL左右值无限分类预排序遍历树算法

    引言 大多数用户都曾在数据库中处理过分层数据(hierarchical data),认为分层数据的管理不是关系数据...

网友评论

    本文标题:预排序遍历树算法小结

    本文链接:https://www.haomeiwen.com/subject/eigmjttx.html