加载三层树的有关问题
加载三层树的问题
现在我有一个数据库Test
表结构和数据如入:
ID Name ParentID
1 中国人 00000000
2 浙江人 1
3 湖北人 1
4 杭州人 2
5 绍兴人 2
6 武汉人 3
7 荆门人 3
8 美国人 00000000
9 纽约人 8
10 华盛顿人8
11 曼哈顿人9
现在要根据他们的ID和ParentID的关系加载到树中,呈现层次关系
请问有没有好的算法,不要用到TreeView的SelectChange事件,要求一次性加载。
高手帮忙啊!
------解决方案--------------------
快速创建树的方法 (抛弃拙劣的数据库结构和算法)
1、现在很多人都使用“父-子结构+递归算法”来显示树型的层次结构,但是不得不说这是一种非常拙劣的方式,下面给大家一种简单方便的数据结构和算法,快速显示树型的层次结构:
2、数据库结构
例如表“国家”可以是这样:
编号 名称
----------
01 中国
0101 吉林省
010101 长春市
010102 吉林市
0102 江苏省
010201 南京市
010202 常州市
02 美国
0201 密歇根州
020101 底特律市
0202 华盛顿州
020201 温哥华市
020202 西雅图市
03 澳大利亚
3、在 TreeView 中显示结构
procedure CreateTree;
const
ID_DEPT = 2;
var
nLevel: Integer;
pNodes: array[0..1023] of TTreeNode;
lpID, lpName: string;
begin
ADODataSet1.Close;
ADODataSet1.CommandText := 'SELECT * FROM [国家] ORDER BY [编号] ';
ADODataSet1.Open;
pNodes[0] := nil;
TreeView1.Items.Clear;
with ADODataSet1.Recordset do
while not Eof do
begin
lpID := Fields[ '编号 '].Value;
lpName := Fields[ '名称 '].Value;
nLevel := Length(lpID) div ID_DEPT;
pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], lpName);
MoveNext;
end;
end;
4、短短 20 行,一次读取数据。有人可能问为什么把 pNodes 的大小设成 1024?你也可以设成 10000,随你便,不过 TreeView 如果有那么多节点早死机了。
------解决方案--------------------
树的快速创建算法,只需读一次数据库.
unit U_CreateTree;
interface
uses
Classes, ComCtrls, ADODB, SysUtils;
type
PPNodedata=^TNodeData;
TNodeData = record
ID:integer;//节点编号
PID:Integer;//父节点编号
Name:string;//节点名称
child:PPNodedata;//孩子节点
brather:PPNodedata;//兄弟节点
end;
PNodeData = PPNodeData;
TTreeFill1 = class(TThread)
TV: TTreeView;
RootID:Integer;
ptr:PPNodeData;
root:PPNodeData;//根节点
PointNode:PPNodeData;
s:array[0..10000] of PPNodeData;
constructor Create(Root_Id:integer;ATreeView: TTreeView);
private
procedure AddTree(Node: TTreeNode; PN: PNodeData);
protected
procedure Execute; override;
end;
implementation
uses
U_Main, DateUtils;
var count,nodeCount:Integer;
//----------
constructor TTreeFill1.Create(Root_Id:integer;ATreeView:TTreeView);
begin
TV:= ATreeView;
TV.Items.Clear;
RootID:=Root_Id;
inherited Create(False);
end;
//----------
procedure TTreeFill1.Execute;
var Query: TADOQuery;
i,j:Integer;
Node: TTreeNode;
begin
FreeOnTerminate := True;
现在我有一个数据库Test
表结构和数据如入:
ID Name ParentID
1 中国人 00000000
2 浙江人 1
3 湖北人 1
4 杭州人 2
5 绍兴人 2
6 武汉人 3
7 荆门人 3
8 美国人 00000000
9 纽约人 8
10 华盛顿人8
11 曼哈顿人9
现在要根据他们的ID和ParentID的关系加载到树中,呈现层次关系
请问有没有好的算法,不要用到TreeView的SelectChange事件,要求一次性加载。
高手帮忙啊!
------解决方案--------------------
快速创建树的方法 (抛弃拙劣的数据库结构和算法)
1、现在很多人都使用“父-子结构+递归算法”来显示树型的层次结构,但是不得不说这是一种非常拙劣的方式,下面给大家一种简单方便的数据结构和算法,快速显示树型的层次结构:
2、数据库结构
例如表“国家”可以是这样:
编号 名称
----------
01 中国
0101 吉林省
010101 长春市
010102 吉林市
0102 江苏省
010201 南京市
010202 常州市
02 美国
0201 密歇根州
020101 底特律市
0202 华盛顿州
020201 温哥华市
020202 西雅图市
03 澳大利亚
3、在 TreeView 中显示结构
procedure CreateTree;
const
ID_DEPT = 2;
var
nLevel: Integer;
pNodes: array[0..1023] of TTreeNode;
lpID, lpName: string;
begin
ADODataSet1.Close;
ADODataSet1.CommandText := 'SELECT * FROM [国家] ORDER BY [编号] ';
ADODataSet1.Open;
pNodes[0] := nil;
TreeView1.Items.Clear;
with ADODataSet1.Recordset do
while not Eof do
begin
lpID := Fields[ '编号 '].Value;
lpName := Fields[ '名称 '].Value;
nLevel := Length(lpID) div ID_DEPT;
pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], lpName);
MoveNext;
end;
end;
4、短短 20 行,一次读取数据。有人可能问为什么把 pNodes 的大小设成 1024?你也可以设成 10000,随你便,不过 TreeView 如果有那么多节点早死机了。
------解决方案--------------------
树的快速创建算法,只需读一次数据库.
unit U_CreateTree;
interface
uses
Classes, ComCtrls, ADODB, SysUtils;
type
PPNodedata=^TNodeData;
TNodeData = record
ID:integer;//节点编号
PID:Integer;//父节点编号
Name:string;//节点名称
child:PPNodedata;//孩子节点
brather:PPNodedata;//兄弟节点
end;
PNodeData = PPNodeData;
TTreeFill1 = class(TThread)
TV: TTreeView;
RootID:Integer;
ptr:PPNodeData;
root:PPNodeData;//根节点
PointNode:PPNodeData;
s:array[0..10000] of PPNodeData;
constructor Create(Root_Id:integer;ATreeView: TTreeView);
private
procedure AddTree(Node: TTreeNode; PN: PNodeData);
protected
procedure Execute; override;
end;
implementation
uses
U_Main, DateUtils;
var count,nodeCount:Integer;
//----------
constructor TTreeFill1.Create(Root_Id:integer;ATreeView:TTreeView);
begin
TV:= ATreeView;
TV.Items.Clear;
RootID:=Root_Id;
inherited Create(False);
end;
//----------
procedure TTreeFill1.Execute;
var Query: TADOQuery;
i,j:Integer;
Node: TTreeNode;
begin
FreeOnTerminate := True;