我正在制作一个程序,用户构建目录(不是在Windows中,在我的应用程序中),并且在这些文件夹中有子文件夹等等;每个文件夹必须包含文件夹或文档。最好使用什么数据结构?请注意,用户可以选择一个子文件夹并搜索其中及其子文件夹中的文档。而且我不想限制文件夹或子文件夹级别。
这就是我所做的:
数据库中的每条记录都有两个字段:ID 和 ParentID。 ID 为 4-5 个字符(Base36、a-z:0-9 或类似内容)。父 ID 是父完整结构的串联...
所以...
这个结构:
Root
Folder1
Folder2
Folder3
Folder4
Folder5
Folder6
将表示如下:
ID ParentID Name
0000 NULL ROOT
0001 0000 Folder1
0002 0000 Folder2
0003 00000002 Folder3
0004 0000 Folder4
0005 00000004 Folder5
0006 000000040005 Folder6
我喜欢这种结构,因为如果我需要查找文件夹下的所有文件,我可以执行如下查询:
SELECT * FROM Folders WHERE ParentID LIKE '0000%' -- to find all folders under Folder1
要删除文件夹及其所有子文件夹:
DELETE FROM Folders WHERE ID='0004' AND ParentID LIKE '00000004%'
要移动文件夹及其子文件夹,您必须将使用同一父文件夹的所有记录更新为新的父文件夹。
我不想初始化文件夹或子文件夹级别
对此的一个明显限制是子文件夹的数量仅限于 ParentID 字段的大小。
我可以想到几种构建此结构的方法,但没有什么比显而易见的更好的了:
使用实际的文件系统。
我会考虑使用某种树数据结构
我应该推荐 B+ Tree ....你可以轻松使用索引(页面、文件夹等)和所有。
B+ 树 http://commons.wikimedia.org/wiki/File:Btree.png
了解更多信息: http://ozark.hendrix.edu/~burch/cs/340/reading/btree/index.html
我知道这个问题是专门要求数据结构的,但是......
如果您使用面向对象的语言,也许您可以使用复合设计模式,它非常适合这种类型的层次树状结构。你得到了你所要求的。
大多数面向对象语言都带有某种文件系统抽象,所以我将从这里开始。如果需要的话,然后将其子类化。
我希望目录是一个对象数组,例如目录或文件。
可以使用m-way树数据结构
扁平列表有其优点,例如更容易处理,并且可能占用更小的空间。为了避免重复,只需对完整路径进行排序,然后按名称(不带路径)存储每个项目(文件或文件夹)。
level:int name:string (+ other attributes such as mtime, size)
列表中的项目隐式是前一个较低级别条目的子项。任何目录的所有内容都可以在紧随其后的行中找到,直到较低级别。
OP结构变成(省略根删除行并递减级别)
0 Root
1 Folder1
1 Folder2
2 Folder3
1 Folder4
2 Folder5
3 Folder6
作为替代方案,不是为每个条目级别存储其中有多少下一个条目(可能递归得更深)。使得递归地获取任何文件夹变得更加容易,但使列表难以操作,所以我不喜欢它。关卡很简单:
loc = []
targetlevel = None
for [level, name, attrs] in table:
# Stop at end of directory
if targetlevel is not None and level <= targetlevel:
break
# Construct path fragments in loc for a full path
loc = loc[:level] + [name]
fullpath = "/".join(loc)
if fullpath == "path/to/search":
targetlevel = level
# If found, report back all items that belong to target
if targetlevel is not None:
yield fullpath, attrs