无限级分类:预排序遍历树算法与递归
2011-11-22 17:09
316 查看
1 lft 代表左 left
2 rgt 代表右 right
下面这个图是一个典型的结构
1 查看整个树(A)有多少节点(包含自己)
直接看根节点就行了 (right-left+1)/2 = (20-1+1)/2 = 10
这个数有10个节点
2 查看从节点A到E的路径
select * from tree where lft between 1 and 6 and rgt between 7 and 20 order by lft
得到的结果是A,B,D,E 这4个节点的数据,且按照访问路径的顺序
3 得到某个节点下面的所有节点,且按照树状结构返回
用B做例子
select * from tree t inner join tree t2 on (t.lft > t2.lft and t.rgt<t2.rgt) and
t2.Id=@Id
拿到的结果是 C,D,E,F,而且顺序也是正确的。
要包含节点本身则:
select * from tree t inner join tree t2 on (t.lft between t2.lft and t2.rgt) and
t2.Id=@Id
4 查询所有无分支的节点 条件:右边 = 左边L + 1
SELECT *
FROM tree WHERE
rgt =
lft + 1;
5插入新节点
算法详解:
1.所有分类 左边和右边的值 > 插入节点的左边节点记录的右值 的全部 + 2
2.插入节点 左值 = 插入位置左边节点记录的右值 + 1, 右值 = 插入位置左边节点记录的右值 + 2
例子:
在 R = 9(L8, R9)与 L = 10(L10,R11) 节点之间插入一个新节点
那么所有 左值 和 右值 > 9 的节点的左值和右值需要 + 2
例如新节点右边的节点(L10,R11)左值右值都需要 + 2 那么插入后的新值为 L12 R13
新节点的左值为 9 + 1 = 10 右值为 9 + 2 = 11
SQL语句实现
LOCK TABLE
nested_category WRITE;
SELECT @myRight
:=
rgt FROM nested_category
WHERE name
= 'TELEVISIONS';
UPDATE nested_category
SET rgt
= rgt +
2 WHERE
rgt > @myRight;
UPDATE nested_category
SET lft
= lft +
2 WHERE
lft > @myRight;
INSERT INTO
nested_category(name,
lft,
rgt) VALUES('GAME CONSOLES',
@myRight
+ 1,
@myRight
+ 2);
UNLOCK TABLES;
6删除新节点
删除节点的算法与添加一个节点的算法相反
删除一个没有子节点的节点
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'GAME CONSOLES';
DELETE FROM
nested_category WHERE
lft BETWEEN @myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
@myWidth
WHERE rgt >
@myRight;
UPDATE nested_category
SET lft
= lft -
@myWidth
WHERE lft >
@myRight;
UNLOCK TABLES;
删除一个分支节点和它所有的子节点
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'MP3 PLAYERS';
DELETE FROM
nested_category WHERE
lft BETWEEN @myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
@myWidth
WHERE rgt >
@myRight;
UPDATE nested_category
SET lft
= lft -
@myWidth
WHERE lft >
@myRight;
UNLOCK TABLES;
删除一个节点后移动其字节点到
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'PORTABLE ELECTRONICS';
DELETE FROM
nested_category WHERE
lft = @myLeft;
UPDATE nested_category
SET rgt
= rgt -
1,
lft = lft
- 1
WHERE lft BETWEEN
@myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
2 WHERE
rgt > @myRight;
UPDATE nested_category
SET lft
= lft -
2 WHERE
lft > @myRight;
UNLOCK TABLES;
使用这种方法比使用递归快数十倍
预排序遍历树算法的核心就是牺牲了写的性能来换取读取的性能
当你的应用程序 读压力>写压力 时,可以尝试使用
2 rgt 代表右 right
下面这个图是一个典型的结构
1 查看整个树(A)有多少节点(包含自己)
直接看根节点就行了 (right-left+1)/2 = (20-1+1)/2 = 10
这个数有10个节点
2 查看从节点A到E的路径
select * from tree where lft between 1 and 6 and rgt between 7 and 20 order by lft
得到的结果是A,B,D,E 这4个节点的数据,且按照访问路径的顺序
3 得到某个节点下面的所有节点,且按照树状结构返回
用B做例子
select * from tree t inner join tree t2 on (t.lft > t2.lft and t.rgt<t2.rgt) and
t2.Id=@Id
拿到的结果是 C,D,E,F,而且顺序也是正确的。
要包含节点本身则:
select * from tree t inner join tree t2 on (t.lft between t2.lft and t2.rgt) and
t2.Id=@Id
4 查询所有无分支的节点 条件:右边 = 左边L + 1
SELECT *
FROM tree WHERE
rgt =
lft + 1;
5插入新节点
算法详解:
1.所有分类 左边和右边的值 > 插入节点的左边节点记录的右值 的全部 + 2
2.插入节点 左值 = 插入位置左边节点记录的右值 + 1, 右值 = 插入位置左边节点记录的右值 + 2
例子:
在 R = 9(L8, R9)与 L = 10(L10,R11) 节点之间插入一个新节点
那么所有 左值 和 右值 > 9 的节点的左值和右值需要 + 2
例如新节点右边的节点(L10,R11)左值右值都需要 + 2 那么插入后的新值为 L12 R13
新节点的左值为 9 + 1 = 10 右值为 9 + 2 = 11
SQL语句实现
LOCK TABLE
nested_category WRITE;
SELECT @myRight
:=
rgt FROM nested_category
WHERE name
= 'TELEVISIONS';
UPDATE nested_category
SET rgt
= rgt +
2 WHERE
rgt > @myRight;
UPDATE nested_category
SET lft
= lft +
2 WHERE
lft > @myRight;
INSERT INTO
nested_category(name,
lft,
rgt) VALUES('GAME CONSOLES',
@myRight
+ 1,
@myRight
+ 2);
UNLOCK TABLES;
6删除新节点
删除节点的算法与添加一个节点的算法相反
删除一个没有子节点的节点
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'GAME CONSOLES';
DELETE FROM
nested_category WHERE
lft BETWEEN @myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
@myWidth
WHERE rgt >
@myRight;
UPDATE nested_category
SET lft
= lft -
@myWidth
WHERE lft >
@myRight;
UNLOCK TABLES;
删除一个分支节点和它所有的子节点
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'MP3 PLAYERS';
DELETE FROM
nested_category WHERE
lft BETWEEN @myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
@myWidth
WHERE rgt >
@myRight;
UPDATE nested_category
SET lft
= lft -
@myWidth
WHERE lft >
@myRight;
UNLOCK TABLES;
删除一个节点后移动其字节点到
LOCK TABLE
nested_category WRITE;
SELECT @myLeft
:=
lft, @myRight
:=
rgt, @myWidth
:=
rgt - lft
+ 1
FROM nested_category
WHERE name
= 'PORTABLE ELECTRONICS';
DELETE FROM
nested_category WHERE
lft = @myLeft;
UPDATE nested_category
SET rgt
= rgt -
1,
lft = lft
- 1
WHERE lft BETWEEN
@myLeft
AND @myRight;
UPDATE nested_category
SET rgt
= rgt -
2 WHERE
rgt > @myRight;
UPDATE nested_category
SET lft
= lft -
2 WHERE
lft > @myRight;
UNLOCK TABLES;
使用这种方法比使用递归快数十倍
预排序遍历树算法的核心就是牺牲了写的性能来换取读取的性能
当你的应用程序 读压力>写压力 时,可以尝试使用
相关文章推荐
- 预排序遍历树算法(非递归无限极分类算法)
- 预排序遍历树算法(非递归无限极分类算法)
- 预排序遍历树算法(非递归无限极分类算法)学习笔记
- 预排序遍历树算法(非递归无限极分类算法)
- 预排序遍历树算法(非递归无限极分类算法)学习笔记
- php树型无限级分类结构[预排序遍历树算法]
- (转)无限级分类的非递归实现(存储过程版)(细微修正)
- CI框架(无限级分类+递归)
- CI框架(无限级分类+递归)
- php学习笔记六--无限级分类、递归转义
- 无限级分类的非递归实现(存储过程版)
- php递归无限级分类【先序遍历算】,获取任意节点下所有子孩子
- PHP无限级分类的实现(不使用递归)
- CI框架(无限级分类+递归)
- CI框架(无限级分类+递归)
- php+mysql无限级分类(非递归)
- 无限级分类的实现(非递归--存储过程版)
- 无限级分类的非递归实现(存储过程版)
- php非递归无限级分类.
- 无限级分类递归的使用