根据数据库表中记录自动构造一棵结构树的一种高效算法(0分)

  • 主题发起人 主题发起人 wuqiu
  • 开始时间 开始时间
W

wuqiu

Unregistered / Unconfirmed
GUEST, unregistred user!
//========================================================================
//想看到详细的图文信息,请参阅 http://www.lvyin.net/article/list.asp?id=35
//欢迎光临 ★绿荫网络★ www.lvyin.net ★
//========================================================================
unit BuildTreeUnit;

interface

uses
DB, ADODB, ComCtrls;

// 定义树结点对数据库表记录对应的结构体
type
PNode = ^TNode;
TNode = record
FID:integer;
// 记录的ID号
FBM:TBookMark;
// 定位记录的指针(书签)
end;

function BuildTree(DataSet: TADODataSet;
TV: TTreeView;
SelfField,SelfName,ParentField:String):boolean;

implementation

function BuildTree(DataSet: TADODataSet;
TV: TTreeView;
SelfField,SelfName,ParentField:String):boolean;
{ 以下子函数为在表中查找第一个PNode=AIndex的记录}
function FindKey(AIndex: integer;
FFirst:boolean): boolean;
begin
Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
end;
{ 以下函数在FindKey的基础上找出下一个符合的记录}
function FindNext(AIndex: integer): boolean;
begin
DataSet.Next;
if DataSet.Eof then
Result:=false
else
Result:=DataSet.FieldValues[ParentField]=AIndex;
if not Result then
DataSet.Prior;
end;
{ 以下函数据构造当前结点的一级子树 }
function GetChildNode(index: integer;
ANode: TTreeNode):integer;
var
MyNode:PNode;
Node:TTreeNode;
begin
if FindKey(index,true) then
begin
new(MyNode);
with DataSetdo
begin
MyNode^.FID :=FieldValues[SelfField];
MyNode^.FBM :=GetBookmark;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
Result:=1;
while FindNext(index)do
begin
new(MyNode);
with DataSetdo
begin
MyNode^.FID :=FieldValues[SelfField];
MyNode^.FBM :=GetBookmark;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
Result:=Result+1;
end;
end
else
Result:=0;
end;
{ 以下函数据以ANode 为结当,构造一棵属于自己的子树}
procedure BuildMe(AIndex: integer;
ANode: TTreeNode);
var
NodeNum:integer;
Node:TTreeNode;
i:integer;
begin
NodeNum:=GetChildNode(AIndex,ANode);
if NodeNum>0 then
begin
if ANode=nil then
Node:=TV.Items.GetFirstNode
else
Node:=ANode.getFirstChild;
for i:=1 to NodeNumdo
begin
BuildMe(PNode(Node.Data)^.FID,Node);
Node:=ANode.GetNextChild(Node);
end;
end;
end;
// 组合部份
begin
if (DataSet=nil) or (DataSet.Active =false) then
Result:=false
else
if (TV=nil) then
Result:=false
else
begin
TV.Items.Clear;
BuildMe(0,nil);
Result:=true;
end;
end;

end.
 
[8D]
So good!
 
学习学习
 
我的方法:
使用的是递归。userid不用管,直接根据parentid的值得出一个树
procedure Tvari.filltree(parentid, userid: integer;
temptreenode: TfcTreeNode);
var
tempadoq: TADOQuery;
tempnode: TfcTreeNode;
i: integer;
begin

tempadoq := TADOQuery.Create(self);
tempadoq.Connection := DataM.adoc;
with tempadoqdo
begin
sql.Add('select * from urlgroup where parentid = ' + inttostr(parentid));
sql.Add(' and userid = ' + inttostr(userid) + ' order by parentid ASC');
open
end;

for i := 1 to tempadoq.RecordCountdo
begin
if tv.Items.Count = 0 then
begin
tempnode := tv.Items.AddFirst(nil, tempadoq.Fields[3].AsString);
end
else
begin
tempnode := tv.Items.AddChild(temptreenode, tempadoq.Fields[3].AsString);
end;
tempnode.StringData := tempadoq.Fields[0].AsString;
tempnode.StringData2 := 'F';
filltree(tempadoq.Fields[0].AsInteger, userid, tempnode);
tempadoq.Next;
end;
tempadoq.Free;
end;
 
后退
顶部