假设您有一个存储有序树层次结构的平面表:
Id Name ParentId Order
1 'Node 1' 0 10
2 'Node 1.1' 1 10
3 'Node 2' 0 20
4 'Node 1.1.1' 2 10
5 'Node 2.1' 3 10
6 'Node 1.2' 1 20
Run Code Online (Sandbox Code Playgroud)
这是我们所拥有的图表[id] Name
.根节点0是虚构的.
[0] ROOT / \ [1] Node 1 [3] Node 2 / \ \ [2] Node 1.1 [6] Node 1.2 [5] Node 2.1 / [4] Node 1.1.1
您将使用什么简约方法将其输出为HTML(或文本,就此而言)作为正确排序,正确缩进的树?
进一步假设你只有基本的数据结构(数组和散列图),没有带有父/子引用的花哨对象,没有ORM,没有框架,只有你的双手.该表表示为结果集,可以随机访问.
伪代码或普通英语是可以的,这纯粹是一个概念性的问题.
额外问题:在RDBMS中存储这样的树结构是否有根本更好的方法?
编辑和补充
回答一个评论者(Mark Bessey的)问题:根节点不是必需的,因为它永远不会被显示.ParentId = 0是表示"这些是顶级"的惯例.Order列定义了如何对具有相同父节点的节点进行排序.
我所谈到的"结果集"可以被描绘成一组哈希图(保留在该术语中).因为我的例子意味着已经存在.有些答案会加倍努力并首先构建它,但那没关系.
树可以任意深.每个节点可以有N个子节点.不过,我并没有考虑到"数百万条目".
不要将我选择的节点命名('Node 1.1.1')误认为是依赖的东西.节点同样可以称为"Frank"或"Bob",不暗示命名结构,这只是为了使其可读. …
我一直试图解决这个问题,但我没有到达任何地方.希望有人可以来救我.
我的问题是我使用邻接列表数据模型在mysql中生成我的层次结构数据.我可以将表(见下文)检索到一个多维数组中,每个项目都有一个关联数组.我想要做的是,一旦我得到这个数组,我想得到另一个数组,包含父ID(包括父项)下的所有节点(子,孙等).我只是无法锻炼如何编码tihs in PHP.
在MySQL中,我的表格如下所示:
id name parent_id
1 Electronics 0
2 Televisions 1
3 Portable Electronics 1
4 Tube 2
5 LCD 2
6 Plasma 2
7 Mp3 Players 3
8 CD Players 3
9 2 Way Radios 3
10 Flash 7
Run Code Online (Sandbox Code Playgroud)
我可以使用此代码将所有行检索到关联数组中.
$r = mysql_query("SELECT * FROM test ");
$data = array();
while($row = mysql_fetch_assoc($r)) {
$data[] = $row;
}
Run Code Online (Sandbox Code Playgroud)
获取结果:
Array
(
[0] => Array
(
[id] => 1
[name] => Electronics
[parent_id] => 0
)
[1] …
Run Code Online (Sandbox Code Playgroud) 我看到了这个答案,我希望他是不正确的,就像有人不正确地说主键在列上而我无法在多列上设置它.
这是我的桌子
create table Users(id INT primary key AUTO_INCREMENT,
parent INT,
name TEXT NOT NULL,
FOREIGN KEY(parent)
REFERENCES Users(id)
);
+----+--------+---------+
| id | parent | name |
+----+--------+---------+
| 1 | NULL | root |
| 2 | 1 | one |
| 3 | 1 | 1down |
| 4 | 2 | one_a |
| 5 | 4 | one_a_b |
+----+--------+---------+
Run Code Online (Sandbox Code Playgroud)
我想选择用户ID 2并递归,所以我得到了所有直接和间接的孩子(所以id 4和5).
如何以这样的方式编写它?我在postgresql和sqlserver中看到了递归.