Delphi 什么数据结构最适合VirtualStringTree?
我想所有使用过Delphi的VirtualStringTree的人都会同意这是一个很好的控件。它是一个“虚拟”控件(您的数据必须保存在其他地方),所以我在想什么样的数据结构最适合这样的任务?IMO认为数据结构必须支持层次结构,它必须快速且易于扩展。最简单的实现是使用一个记录,这是可以找到的大多数文档所建议的。但是如果你需要做一些快速查找,计算总数,等等呢?与VirtualStringTree一起使用的是什么数据结构 EDIT1:我正在使用Delphi 2010 好的,我会尽量提供更多关于我的要求的细节。 数据大小可能非常多变,从1到数千项。每个项可以包含多个字符串、整数值。我需要随机访问,在应用程序生命周期内,我的数据可以多次更改。良好的性能是非常可取的。我还需要保存和重新加载数据 EDIT2: 我得到了一个答案,所以我将尝试评论我的观点。多林,谢谢你的回答,但是 我认为你们的结构不太方便。 1) 它不涉及层次结构。 2) 对每个节点使用单独的TStringList或TList对我来说不是很有效。使用这种实现,我只能查找当前节点的数据,但不能有效地在整个树中搜索 我认为这个数据结构一定像一棵树。它必须具有能够添加子节点的节点。然后我就可以在OnInitNode事件中获取节点的数据,检查我的节点是否有一些子节点,如果有,设置ivsHasChildren标志,然后在OnInitChildren事件中设置正确的子节点计数。稍后在OnGetText事件中,我可以从节点结构中获取所需的数据,并根据列索引将其设置为CellText。我的想法是拥有一个单独的数据结构,并使用它执行所有需要的操作,而无需使用VirtualStringTree。希望有人明白我的意思:)Delphi 什么数据结构最适合VirtualStringTree?,delphi,data-structures,virtualtreeview,Delphi,Data Structures,Virtualtreeview,我想所有使用过Delphi的VirtualStringTree的人都会同意这是一个很好的控件。它是一个“虚拟”控件(您的数据必须保存在其他地方),所以我在想什么样的数据结构最适合这样的任务?IMO认为数据结构必须支持层次结构,它必须快速且易于扩展。最简单的实现是使用一个记录,这是可以找到的大多数文档所建议的。但是如果你需要做一些快速查找,计算总数,等等呢?与VirtualStringTree一起使用的是什么数据结构 EDIT1:我正在使用Delphi 2010 好的,我会尽量提供更多关于我的要求
EDIT3:我发现了非常有趣的JclTrees单元,乍一看可以用来实现我所寻找的目标。它属于图书馆。由于缺乏像样的文档,很难快速调查它的功能。当我有更多的时间时,我可能会更深入地研究它 您尚未指定Delphi版本,因此: 我建议使用记录(我不确定他们在哪个版本的Delphi中为记录添加了方法,我从D7迁移到D2010),这样您就可以得到如下结果:
type
TMyRecordWithMethods = record
function GetMeAResult: Integer;
procedure DoSomething(const AInParam: Integer; var AOutParam: Integer);
end;
如果您的Delphi版本不支持带有方法的记录,并且您确实需要用于节点的方法,那么您必须使用对象来实现这一点,还可以查看泛型
因为你只需要持有几千件物品,所以我建议使用泛型(无需重新发明轮子IMHO)
现在需要实现加载和保存,我建议使用TFileStream保存和加载—非常简单
伪代码,抱歉,部分代码没有时间:-\
a) 保存内容:
- 保存TMyFileHeader变量中的项数并将其写入文件
- 对于树中的每个项目,保存整数列表,保存字符串列表
- 读取文件头——这样您就知道需要从文件中读取多少项
- 对索引:=0执行一次计数-1从文件中读取项
FileStream.WriteBuffer(PChar(AStringList.Text)^, Length(AStringList.Text) * SizeOf(Char));
我希望这有帮助,代码的实际实现取决于你,玩得开心 您可以使用TXMLDocument 如果您想要对放入的内容进行更多控制,我建议您创建一个描述所需结构的xsd,并使用XML数据绑定向导生成可以使用的Delphi代码 此模式
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:complexType name="itemType">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="itemlist" type="itemlistType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemlistType">
<xs:sequence>
<xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="itemlist" type="itemlistType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
好的,因为给出的答案并没有解决我的问题,所以我编写了自己的树数据结构,它模仿TVirtualStringTree,处理我在问题中提到的所有问题。现在,我可以选择只使用我的数据结构,其中的所有更改将自动更新VirtualStringTree。我想我以后会把源代码上传到某个地方,并在这里发布链接。谢谢你的回答
编辑:我已将源代码上传到谷歌代码:。有一个小演示演示了它是如何工作的。这并没有解决hierarchy@DavidHeffernan根据他的“实际”需求,他可以做出妥协,如果他需要创建一百万个节点,使用对象将消耗大量内存(现在当然都会消耗到目标系统),但记录消耗的内存会更少,安湖非常欢迎你来给我一个好答案:-P@Dorin我什么也没说。不管它值多少钱,我认为记录是好的。也就是说,对象不再使用任何内存—ToObject没有成员字段。我的观点是,问题是关于层次结构,而不是如何在节点中存储信息。我在问题中提到,记录是一个很好的解决方案,但使用记录并不能解决David所说的一些问题。@David拜托,伙计,别这么防御性:)但是关于“也就是说,对象不再使用任何内存”--为什么会有人使用没有字段的对象?这同样适用于记录,但如果在对象中添加一个整型字段,在记录中添加一个整型字段,当您查看时,您将看到差异。InstanceSize,也就是说,乘以项目(和子项目)的数量,您将得到大量内存浪费+创建和释放过程,这将占用相当多的CPU周期(如果有很多项,请再说一遍)。@Lina您能告诉我们更多有关您希望存储的数据的信息吗?数据有多大?它在您的进程生命周期内如何变化?您需要随机访问吗?性能限制是什么?目前我正在考虑
FileStream.WriteBuffer(PChar(AStringList.Text)^, Length(AStringList.Text) * SizeOf(Char));
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:complexType name="itemType">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="itemlist" type="itemlistType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemlistType">
<xs:sequence>
<xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="itemlist" type="itemlistType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
IXMLRoot = interface(IXMLNode)
['{16C6C960-58B7-400C-9E46-7ACC7BEF276F}']
{ Property Accessors }
function Get_Itemlist: IXMLItemlistType;
{ Methods & Properties }
property Itemlist: IXMLItemlistType read Get_Itemlist;
end;
{ IXMLItemlistType }
IXMLItemlistType = interface(IXMLNodeCollection)
['{59F80BAC-887E-48DF-8288-95276BF9DCE7}']
{ Property Accessors }
function Get_Item(Index: Integer): IXMLItemType;
{ Methods & Properties }
function Add: IXMLItemType;
function Insert(const Index: Integer): IXMLItemType;
property Item[Index: Integer]: IXMLItemType read Get_Item; default;
end;
{ IXMLItemType }
IXMLItemType = interface(IXMLNode)
['{1218DD35-C3EF-40E6-831A-1A4AA0782C36}']
{ Property Accessors }
function Get_Id: Integer;
function Get_Name: WideString;
function Get_Itemlist: IXMLItemlistType;
procedure Set_Id(Value: Integer);
procedure Set_Name(Value: WideString);
{ Methods & Properties }
property Id: Integer read Get_Id write Set_Id;
property Name: WideString read Get_Name write Set_Name;
property Itemlist: IXMLItemlistType read Get_Itemlist;
end;