标题:树形结构结点编码(在mysql等关系数据库里存取树形结构)
只看楼主
yaojf1
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2018-8-11
 问题点数:0 回复次数:0 
树形结构结点编码(在mysql等关系数据库里存取树形结构)
新人,发个新帖拜拜山头。

有项目实践经验的同学可能碰到过这样的问题:怎样才能高效地在mysql数据库里遍历树形结构。网络上有一些方法,但也各有优缺点。这是我实现的一套算法,看看能不能抛砖引玉,给这类问题提供一个新的思路。

主要目的是给树形结构的每个结点都赋予一个唯一的编号,并可以根据任一结点编号计算出其双亲结点,所有祖先结点,兄弟结点,孩子结点的编号。

实现原理是:

1、任何一棵树都可以用一棵唯一的二叉树来表示,如:

转换规则是:树的根结点转换成二叉树的根结点,根结点的第一个孩子结点转换成根结点的左孩子,根结点的第二个孩子转换成第一个孩子的右孩子,第三个孩子转换成第二个孩子的右孩子....依次类推。
然后对除根结点外其余结点所表示的子树也做上面的转换。

有学习过数据结构的同学可能会记得,这是孩子兄弟表示法,也就是说,在二叉树里每个结点的左孩子表示它的第一个孩子,而每个结点的右孩子表示它的右兄弟。

2、如果对一棵满二叉树的各个结点从1开始自上而下,自左而右开始编号,

那么编号为i的结点,其左孩子的编号为:2i,右孩子的编号为:2i+1,双亲结点的编号为:i/2。这个规律可以从图上看出来并用归纳法证明。

3、在二叉树上得到的结点编号,就是这棵二叉树所表示的树的各个结点的编号。如图

所不同的是,孩子结点和双亲结点的计算公式。在树结构中,一个编号为n的结点,其第i(i=1,2,3……)个孩子结点的编号为:(2^i)*n+2^(i-1)-1。
而从编号为n的结点得到其双亲结点编号的算法是,如果n是偶数,则其双亲结点编号为:n/2;否则反复进行n<-n/2 的操作,直到n为偶数为止。然后再做一次n<-n/2操作就得到双亲结点的编号。

4、由上面所说的编码方法,对一棵树从根结点开始,自上而下,自左而右进行编号的话,就可以从任一结点的编号计算出其双亲结点,所有祖先结点,兄弟结点,孩子结点的编号。

5、本文最后的附件里有2个java文件,提供了一些方法,可以根据当前结点编号计算其它结点的编号。编号是64进制数,用java语言实现。主要接口有:

    (1)TreeCodeSet.root();这个方法返回树的根结点编码。
    (2)TreeCodeSet.child(String code, int i);这个方法由树中某一结点的编码计算出其第i个(i=1,2,3,4,....)孩子结点的编码。
    (3)TreeCodeSet.parent(String code);这个方法由树中某一结点的编码计算出其父结点的编码。
    (4)TreeCodeSet.forefather(String code);这个方法由树中某一个结点的编码计算出其所有祖先结点的编码。
     ......
   
6、在给树的结点编号时,可以首先给根结点编号(调用TreeCodeSet.root()方法获取根结点编号),然后从根结点开始由上而下给每个结点的子节点编号(调用TreeCodeSet.child(String code, int i)获取各个子节点编号)。
   给所有结点编号后,就可以根据编号在数据库中查找 父结点,子结点,祖先结点,兄弟结点。如果要给树插入新结点,给新结点编号方法相同。

7、这个编码表对存取在mysql数据库的树形结构应该有帮助。需要注意的是数据库里存储编码的字段,排序规则必须是大小写敏感的。

8、附件。
src.zip (2.64 KB)


[此贴子已经被作者于2018-8-11 05:38编辑过]

搜索更多相关主题的帖子: 结构 结点 编码 编号 孩子 
2018-08-11 03:55



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-489144-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.888142 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved