下面是我用来表示树结构的类,用于显示游戏存档格式的文件和文件夹。
public class DirNode : INotifyPropertyChanged
{
public String Name { get; set; }
public int Index { get; private set; }
public int FileIndex { get; private set; }
public int Type { get; private set; }
public List<DirNode> Directories { get; set; }
public List<FileNode> Files { get; set; }
public DirNode(String n, int index, int type, int fi)
{
Name = n;
Directories = new List<DirNode>();
Files = new List<FileNode>();
Index = index;
Type = type;
FileIndex = fi;
}
}
下面是我正在使用的类的方法,用于将路径字符串解析为树。当我只加载一个存档时它运行得很好,但是当试图“挂载”多个档案时,效率低下肯定显示
public void AddPath(String[] path, int index, int fileIndex)
{
if (path.Length > 1) //It's a Folder;
{
bool found = false;
int i = 0;
while (i < this.Directories.Count && found == false)//search to see if this folder already exists
{
if (this.Directories[i].Name == path[0])
{
found = true;
String[] newPath = new String[path.Length - 1];
Array.Copy(path, 1, newPath, 0, newPath.Length);
this.Directories[i].AddPath(newPath, index,fileIndex);
return;
}
i++;
}
if (found == false) //new item
{
DirNode dn = new DirNode(path[0], -1, 0,fileIndex);
this.Directories.Add(dn);
String[] newPath = new String[path.Length - 1];
Array.Copy(path, 1, newPath, 0, newPath.Length);
this.Directories[this.Directories.Count - 1].AddPath(newPath, index,fileIndex);
}
}
else if (path.Length == 1) //a file!
{
DirNode fn = new DirNode(path[0], index, 1,fileIndex);
this.Directories.Add(fn);
return;
}
else
{
//really no reason why we should be here.
return;
}
}
我知道BinarySearch需要一个预先排序的列表,这个列表不起作用,因为列表在组装树之后才会排序。但它最终是排序的,所以Hash也不会起作用。如果有人有任何想法,我很乐意听到他们的意见。
当然,如果有人知道.NET DirectoryInfo类的虚拟实现,那可能会更好。
答案 0 :(得分:1)
为什么不将项目存储在插入时排序的目录和文件中,以便您可以在每个目录级别上实际执行二进制搜索? List类中的BinarySearch()
将为您提供索引(如果找到)和索引补充(使用~
运算符),如果找不到,那么您就知道需要插入新项目的索引程。
像这样的东西(没有以任何方式测试过,只是在编辑器中被黑了):
用于比较两个DirNodes
的名称的类:
internal class DirNodeNameComparer: IComparer<DirNode> {
public static readonly DirNodeNameComparer Default = new DirNodeNameComparer();
public int Compare(DirNode x, DirNode y) {
return string.Compare(x.Name, y.Name);
}
}
更新了您的AddPath方法以保留已排序的表示形式:
public void AddPath(String[] path, int index, int fileIndex)
{
if (path.Length > 1) //It's a Folder;
{
DirNode dn = new DirNode(path[0], -1, 0, fileIndex);
int i = this.Directories.BinarySearch(dn, DirNodeNameComparer.Default);
if (i < 0) {
i = ~i;
this.Directories.Insert(i, dn);
}
String[] newPath = new String[path.Length - 1];
Array.Copy(path, 1, newPath, 0, newPath.Length);
this.Directories[i].AddPath(newPath, index,fileIndex);
return;
}
else if (path.Length == 1) //a file!
{
DirNode fn = new DirNode(path[0], index, 1, fileIndex);
int i = this.Directories.BinarySearch(fn, DirNodeNameComparer.Default);
this.Directories.Insert(~i, fn); // really Directories?
return;
}
else
{
//really no reason why we should be here.
return;
}
}