您的位置:首页 > 其它

无限级分类:预排序遍历树算法与递归

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;

使用这种方法比使用递归快数十倍

预排序遍历树算法的核心就是牺牲了写的性能来换取读取的性能

当你的应用程序 读压力>写压力 时,可以尝试使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: