java中的左值右值_利用左值右值实现树状结构

本文介绍了如何在Java中使用左值和右值来操作树状结构,包括查询和修改操作。查询部分涉及获取节点的子节点、路径及子节点总数;修改部分涵盖增加、删除节点以及子树迁移。通过调整左右值实现树结构的动态维护。
摘要由CSDN通过智能技术生成

a9c186fe1c3c

image.png

1. 查询

1.1. 得到节点 Node 下的所有节点,并按树状排序

SELECT * FROM tree WHERE lft BETWEEN Node.Lft AND Node.Rgt ORDER BY lft ASC;

1.2. 得到节点 Node 的路径:

SELECT * FROM tree WHERE lft < Node.Lft AND rgt > Node.Rgt ORDER BY lft ASC;

1.3. 节点 Node 的子节点总数

(Node.Rgt-Node.Lft-1)/2

2. 修改

2.1. 增加一个节点

假设新节点的父节点是 Father,如果,这是它的第一个子节点,

nCurrent = Father.Lft;

否则,假设插入点的前一个兄弟为 Brother,

nCurrent = Brother.Rgt;

改变所有位于新节点右侧的数值:

UPDATE tree SET rgt = rgt+2 WHERE rgt > nCurrent;

UPDATE tree SET lft = lft+2 WHERE lft > nCurrent;

这样就为新插入的节点腾出了空间:

INSERT INTO tree(lft, rgt) VALUES(nCurrent+1, nCurrent+2);

2.2. 删除一个节点 Node

DELETE Node;

UPDATE tree SET rgt = rgt - 2 WHERE rgt > Node.rgt;

UPDATE tree SET lft = lft - 2 WHERE lft > Node.rgt;

2.3. 子树 SubTree 从 Father1 迁移至 Father2

相当于先插入子树,再删掉原来的子树。

子树根的左右值:

nSubTreeLeft = SubTree.Lft;

nSubTreeRight = SubTree.Rgt;

子树上所有的节点数(包括子树的根):

nSubTreeNodeNum = (nSubTreeRight - nSubTreeLeft - 1) / 2 + 1;

如果,这是 Father2 的第一个子节点,

nCurrent = Father2.Lft;

否则,假设插入点的前一个兄弟为 Brother,

nCurrent = Brother.Rgt;

腾子树空间:

UPDATE tree SET lft=lft + 2* nSubTreeNodeNum WHERE lft > nCurrent; UPDATE tree SET rgt=rgt + 2* nSubTreeNodeNum WHERE rgt > nCurrent;

移动子树:

UPDATE tree SET lft = lft + nCurrent + 1 - nSubTreeLeft, rgt = rgt + nCurrent + 1 - nSubTreeLeft WHERE lft BETWEEN nSubTreeLeft AND nSubTreeRight;

删掉原来子树占的空间:

UPDATE tree SET lft=lft -2* nSubTreeNodeNum WHERE lft > nSubTreeRight;

UPDATE tree SET rgt=rgt -2* nSubTreeNodeNum WHERE rgt > nSubTreeRight;

重构左右值

假设表结构类似:

a9c186fe1c3c

image.png

/**

* 重构左右值

*

* @param rootId 根节点id

* @param left 左值开始值

* @return

*/

public int rebuildTree(int rootId, int left) {

int right = left + 1;

List categories = categoryMapper.selectByParentCategoryID(rootId);

for (Category category : categories) {

right = rebuildTree(category.getId(), right);

}

Category category = categoryMapper.selectByPrimaryKey(rootId);

category.setLft(left);

category.setRgt(right);

categoryMapper.updateByPrimaryKey(category);

return right + 1;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值