TreeView 生成树的 算法(50分)

  • 主题发起人 主题发起人 sun100
  • 开始时间 开始时间
S

sun100

Unregistered / Unconfirmed
GUEST, unregistred user!
表SPLBB有4个字段<br>lbbm(编码) lbmc(名称) fjd(父结点) &nbsp;cs(层数)<br>X超市 &nbsp; &nbsp; 00000000 &nbsp; &nbsp; &nbsp;null &nbsp; &nbsp; &nbsp; 0<br>AA &nbsp; &nbsp; &nbsp; &nbsp;01000000 &nbsp; &nbsp; &nbsp;X超市 &nbsp; &nbsp; &nbsp;1<br>AAC &nbsp; &nbsp; &nbsp; 01010000 &nbsp; &nbsp; &nbsp;AA &nbsp; &nbsp; &nbsp; &nbsp; 2<br>AD &nbsp; &nbsp; &nbsp; &nbsp;01010100 &nbsp; &nbsp; &nbsp;AAC &nbsp; &nbsp; &nbsp; &nbsp;3<br>BB &nbsp; &nbsp; &nbsp; &nbsp;02000000 &nbsp; &nbsp; &nbsp;X超市 &nbsp; &nbsp; &nbsp;1<br>BBC &nbsp; &nbsp; &nbsp; 02010000 &nbsp; &nbsp; &nbsp;BB &nbsp; &nbsp; &nbsp; &nbsp; 2<br>&nbsp;close;<br>&nbsp;sql.Clear;<br>&nbsp;sql.Add('select * from splbb &nbsp;order by cs');<br>&nbsp;prepared;<br>&nbsp;open;<br>&nbsp;first;<br>&nbsp;if &nbsp;FieldValues['splbmc']&lt;&gt;null then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TreeView1.Items.AddFirst(nil,FieldValues['splbmc']); //添加 &nbsp;X超市 <br>&nbsp;next;<br>&nbsp;while not eof do<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; for i:=0 to &nbsp;TreeView1.Items.Count-1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if &nbsp;TreeView1.Items.Text=FieldValues['fjd'] then &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//这里要是不判断第4层的 就好了,怎么写呢<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TreeView1.Items.AddChild(TreeView1.Items,FieldValues['splbmc']);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp; &nbsp; next;<br>&nbsp; &nbsp;end;<br>当第4层 &nbsp;有1000个结点的时候 &nbsp;要运行40左右,太慢了,<br>大家有没有更好的算法
 
当第4层 &nbsp;有1000个结点的时候 &nbsp;要运行40秒左右,太慢了,<br>大家有没有更好的算法
 
自己做树啊?为什么不用dxdbtreeview
 
下面来个抛砖引玉<br>如果对于删除则必须配合数据库存储过程才行<br>procedure TB003F.ShowTreeView;<br>var<br>&nbsp; i:integer;<br>begin<br>&nbsp; i:=0;<br>&nbsp; TreeView.Items.Clear;<br>&nbsp; Node:=TreeView.Items.AddChildFirst(nil,'所有分类');<br>&nbsp; Node.StateIndex:=0;<br>&nbsp; Node.SelectedIndex:=0;<br>&nbsp; Node.ImageIndex:=0;<br>&nbsp; //建立各客户的子分类树<br>&nbsp; with QB001 do<br>&nbsp; begin<br>&nbsp; &nbsp; Close;<br>&nbsp; &nbsp; SQL.Clear;<br>&nbsp; &nbsp; SQL.Add('select * From B002 order by B002_2,B002_3,B002_1');<br>&nbsp; &nbsp; Open;<br>&nbsp; &nbsp; First;<br>&nbsp; &nbsp; while not eof do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; //showmessage(FieldByName('B002_4').AsString);<br>&nbsp; &nbsp; &nbsp; if FieldByName('B002_2').AsInteger=1 then//如果级别是1则直接建立节点<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SubNode:=TreeView.Items.AddChildObject(Node,FieldByName('B002_4').AsString,nil);<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; begin //如果级别不是1则先找到其父亲,让其父亲生下它<br>&nbsp; &nbsp; &nbsp; &nbsp; while i&lt;TreeView.Items.Count do//找父亲<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if TreeView.Items.StateIndex=FieldByName('B002_3').AsInteger then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i:=i+1;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; Node:=Treeview.Items;//找到的父亲<br>&nbsp; &nbsp; &nbsp; &nbsp; SubNode:=TreeView.Items.AddChildObject(Node,FieldByName('B002_4').AsString,nil);//生儿子<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; SubNode.StateIndex:=FieldByName('B002_1').AsInteger;<br>&nbsp; &nbsp; &nbsp; SubNode.ImageIndex:=FieldByName('B002_2').AsInteger;<br>&nbsp; &nbsp; &nbsp; SubNode.SelectedIndex:=0;<br>&nbsp; &nbsp; &nbsp; Next;<br>&nbsp; &nbsp; end;<br>&nbsp; end<br>end;
 
你的代码跟资料结构有些对不上哦<br><br>我的方法是用内存换速度,我没有那么多测试资料,你自己试一下看速度是否有改善<br><br>//用于保存父节点的类<br>&nbsp; TDBNodes = class<br>&nbsp; private<br>&nbsp; &nbsp; FNodes: TList;<br>&nbsp; &nbsp; FNames: TStringList; &nbsp;//也可以直接用Node.text<br>&nbsp; public<br>&nbsp; &nbsp; constructor Create;<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; &nbsp; procedure AddNode(ANode: TTreeNode; AName: String);<br>&nbsp; &nbsp; function GetNodeByName(AName: String): TTreeNode;<br>&nbsp; end;<br><br>{ TNode }<br><br>procedure TDBNodes.AddNode(ANode: TTreeNode; AName: String);<br>begin<br>&nbsp; FNodes.Add(ANode);<br>&nbsp; FNames.Add(AName);<br>end;<br><br>constructor TDBNodes.Create;<br>begin<br>&nbsp; FNodes := TList.Create;<br>&nbsp; FNames := TStringList.Create;<br>end;<br><br>destructor TDBNodes.Destroy;<br>begin<br>&nbsp; FNodes.Free;<br>&nbsp; FNames.Free;<br>&nbsp; inherited;<br>end;<br><br>function TDBNodes.GetNodeByName(AName: String): TTreeNode;<br>var<br>&nbsp; Index: Integer;<br>begin<br>&nbsp; Result := nil;<br>&nbsp; if FNames.Find(AName, Index) then<br>&nbsp; &nbsp; Result := TTreeNode(FNodes[Index]);<br>end;<br><br>生成树的代码<br>var<br>&nbsp; i: Integer;<br>&nbsp; ADBNodes: TDBNodes;<br>&nbsp; ANode: TTreeNode;<br>begin<br>&nbsp; ADBNodes := TDBNodes.Create;<br>&nbsp; try<br>&nbsp; &nbsp; with qry1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; close;<br>&nbsp; &nbsp; &nbsp; sql.Clear;<br>&nbsp; &nbsp; &nbsp; sql.Add('select * from splbb &nbsp;order by cs');<br>&nbsp; &nbsp; &nbsp; prepared;<br>&nbsp; &nbsp; &nbsp; open;<br>&nbsp; &nbsp; &nbsp; first;<br>&nbsp; &nbsp; &nbsp; if &nbsp;FieldValues['fjd']&lt;&gt;null then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ANode := TreeView1.Items.AddFirst(nil,FieldValues['lbmc']); //添加 &nbsp;根<br>&nbsp; &nbsp; &nbsp; &nbsp; ADBNodes.AddNode(ANode, ANode.Text);<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create('没有找到根节点');<br>&nbsp; &nbsp; &nbsp; next;<br>&nbsp; &nbsp; &nbsp; while not eof do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ANode := ADBNodes.GetNodeByName(FieldValues['fjd']);<br>&nbsp; &nbsp; &nbsp; &nbsp; if ANode &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ANode := TreeView1.Items.AddChild(ANode, FieldValues['lbmc'])<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create('尽然没找到父节点');<br>&nbsp; &nbsp; &nbsp; &nbsp; if FieldValues['cs'] &lt; 4 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ADBNodes.AddNode(ANode, ANode.Text);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; ADBNodes.Free;<br>&nbsp; end;
 
展开哪个加哪个<br>不必要一次性生成整个树啊<br><br>照楼主的用法<br>每次更新下 还不把人等急死啊<br><br>呵呵
 
我做上万节点的树就是逐层展开的,同意楼上观点,有下级节点的就加个虚节点,点开的时候出发展开过程增加下级就可以了
 
以我的经验,注意以下两点,会快很多:<br>1.先将Treeview设为不可见, 生成完后再显示;<br>2.数据放在ClientDataset中.
 
后退
顶部