创建一棵类似祖谱(也类似传销形式)的树,紧急!!200分!!(200分)

  • 主题发起人 主题发起人 chenby
  • 开始时间 开始时间
C

chenby

Unregistered / Unconfirmed
GUEST, unregistred user!
表结构:
node char(3) 本结点
parent char(3) 父结点 (无父结点则填自己的结点编号)
ifleaf bit 是否是叶结点(1-是,0-否)

在表中父亲结点肯定只有一个,而孩子可能有多个,就是这棵树中每个结点或者没有父结点,
或者只有一个父结点,而每个结点的子结点可以有无限多个,而且孩子结点中还有孩子结点。

类似祖谱:parent 父亲 child 多个孩子 grandchild 多个孙子
类似传销:上线编号 下线编号

如果可以写原代码给我就好了,也可以发给我chenbiyun@china.com

紧急求助!!!
 
这不就是一个 TreeView 吗?
你的数据结构可能不太好,看看这里吧,我原来实现过的。
<a href="DispQ.asp?LID=384107" title="来自:ankeylee">急!用TreeView 实现数据的层次结构($300)</a>

下面的专题我想对你应该也有用:
<a href="DispQ.asp?LID=341512" title="来自:sunny_ok">哪里可以下载DBtreeView控件</a>
<a href="DispQ.asp?LID=280068" title="来自:木木">DBTreeView 的使用</a>
<a href="DispQ.asp?LID=324773" title="来自:chenshan">怎样用treeview实现对数据库的记录显示?</a>
<a href="DispQ.asp?LID=316924" title="来自:liwenhao">treeview控件的多层应用</a>

你在检索框里面查 “Tree” 吧。
 
谢谢BaKuBaKu!!
我原来也看了这些主题但是很多不适用包括你的那种结构我不能用,
因为我需要编号是一样长,而且就算是子结点在树根下也要有这个结点,
有可能有或没有子结点。
龙丹的结构对我来说就比较适用,但不知道是怎么编程实现创建这棵treeview。
{
来自:龙丹 时间:00-11-3 4:44:29 ID:384455
BaKuBaKu的表结构不是很好,因为编码字段的宽度不确定(至少要考虑最大层次问题)。
比较灵活的结构:
部门代码 上级代码 序号 部门名称 ...
AAAA 1 采购部
AAAB AAAA 1 采购一部
AAAC AAAA 2 采购二部
AAAD AAAC 1 采购二部一分部
AAAE AAAC 2 采购二部二分部
.....
AABA AAAA 3 采购三部
....
ABBB 2 销售部
ABBC ABBB 1 销售一部
ABBD ABBB 2 销售二部
....

当然,序号字段不是必须的。
(以前有人提过类似问题)
}
我需要创建好的树是这样的:

0008
0009--1000--1001--1002
|--0008
1000|--1001--1002--1005
|--1003
1001--1002--1005
1002--1005
1003
1004
1005
 
仅仅创建好像太简单了,你还需什么操作呢?
一起写出来把!
 
chenby,你老兄会找地方呀!
创建树本身的算法是比较简单的,但我的程序中有许多管理方面的内容,
以下把与创建有关的代码贴出,没有整理,慢慢看吧。

TDBTreeView=class(TTreeView)
......
procedure TDBTreeView.OpenTree;
begin
FTryOpen:=True;
OpenTables;
Items.Clear;
try
InsertSubTree(CreateSubTreeNode(nil,FRootCaption,'',RootImageIndex),'');
FActive := True;
finally
FTempQuery.Close;
end;
end;

procedure TDBTreeView.InsertSubTree(ParentNode:TDBTreeNode; ParentCode:string);
var
i:integer;
begin
if GetChildRecords(FTempQuery,ParentCode) then
begin
CreateSubNodes(ParentNode,FTempQuery,IDFieldName,MasterFlag);
//若一次全部建立,则递归:
for i:=0 to ParentNode.Count-1 do
InsertSubTree(ParentNode.Item, CodeOfNode(ParentNode.Item));
//否则,在OnChange或OnClick事件中调用此方法
end;
end;

procedure TDBTreeView.CreateSubNodes(ParentNode: TDBTreeNode; DataSet:TDBDataSet; IDField:string; NodeType:integer);
begin
DataSet.First;
while not DataSet.Eof do
begin
CreateSubTreeNode( ParentNode,
TakeNodeLabel(DataSet,NodeType),
DataSet.FieldByName(IDField).AsString,
NodeType);
DataSet.Next;
end;
end;

function TDBTreeView.CreateSubTreeNode(ParentNode:TDBTreeNode; ACaption,ACode:string; NodeFlag:integer):TDBTreeNode;
begin
Result:=Items.AddChild(ParentNode,ACaption) as TDBTreeNode;
Result.NodeFlag := NodeFlag;
Result.SelectedIndex := NodeFlag+1;
SetCodeOnNode(ACode,Result);
end;

function TDBTreeView.GetChildRecords(Query:TQuery; ParentCode:string):boolean;
const
StmtFmt='select * from %s where %s';
OrderStmt='order by %s';
CondFmt1='%s IS NULL or (%0:s='''')';
CondFmt2='(%s=''%s'')';
var
StmtCond:string;
begin
if not CanOpenTree then
begin
Result:=False;
Exit;
end;
Query.Close;
if Assigned(FOnGetChildrenCondition) then
StmtCond:=FOnGetChildrenCondition(Self,ParentCode)
else
begin
if ParentCode='' then
StmtCond:=Format(CondFmt1,[FParentIDFieldName])
else
StmtCond:=Format(CondFmt2,[FParentIDFieldName,ParentCode]);
end;
Query.SQL.Clear;
Query.SQL.Add(Format(StmtFmt,[FTableName,StmtCond]));
if OrderFieldName<>'' then
Query.SQL.Add(Format(OrderStmt,[OrderFieldName]));
Query.Open;
Result:=True;
end;

 
我有一个可互动数据的DBTREE控件,可用于D4/D5
 
To Chenby:
编码字段是固定的,你难道不会在内部增加一个这样的代表层次关系的字段吗?有什么关系呢?
 
其实创建树只是一个小功能,
还有要从最底层即叶结点开始一层层往上一层按比例累计计算一些金额,
有点像传销形式的抽成。
还有要维护这棵树,就是需增删改这张表
 
还有最好不用第三方控件,因为我做的这个系统是比较重要的,需要保险一点
 
树只是一个表现工具,具体的算法需要用程序和数据结构实现。
 
你要做好写3k行-5k行源程序的思想准备!
 
我是这样做的,用递归算法,不用3K-5K行:

1、先建立一个类存放结点数据
TMyData = Class
Node: String[3];
Parent: String[3];
Money: Double;//金额
... //其它数据
Added: Boolean;//是否被加入树的标志
end;

2、用一个TList存放结点数据
var
MyDatas: TList;
......
procedure TForm1.LoadDatasFromQuery;
var
aData: TMyData;
i : integer;
begin
if not Assigned(MyDatas) then
MyDatas := TList.Create;
else
begin //释放旧的数据
for i := 0 to MyDatas.Count - 1 do
begin
aData := MyDatas;
aData.Free;
end;
MyDatas.Clear;
end;
if not Query1.Active then Query1.Open; //打开存放结点的表
Query1.First;
While not Query1.Eof do
begin
aData := TMyData.Create;
aData.Node := Query1.FieldByName('Node').AsString;
aData.Parent := Query1.FieldbyName('Parent').AsString;
aData.Added := False;
... //其它属性赋值
MyDatas.Add(aData);
Query1.Next;
end;
Query1.Close;
end;

3、建立一个递归函数来建树
function TForm1.AddANode(aData: TMyData): TTreeNode; //加入一个结点到树TreeView1中
var
aNode: TTreeNode;
i : Integer;
begin
aNode := nil;
if aData.Added then //如果结点已经被加入则在树中找到此结点
begin
aNode := TreeView1.Items.GetFirstNode();
while aData <> TMyData(aNode.Data) do
aNode := aNode.GetNext();
Result := aNode;
Exit;
end;

if Trim(aData.Parent) <> '' then //如果有父结点,先则加入父结点
for i := 0 to MyDatas.Count - 1 do
if TMyData(MyDatas).Node = aData.Parent then
begin
aNode := AddANode(TMyData(MyDatas));
break;
end;

Result := TreeView1.Items.AddChildObject(aNode, aData.Node, aData); //加入结点
aData.Added := True; //置标志状态
end;

在另一函数(例:BuildTree)中写入一些简单的语句
procedure TForm1.BuildTree;
var
i : integer;
begin
...
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
LoadDatasFromQuery;
for i := 0 to MyDatas.Count - 1 do
if not TMyData(MyDatas).Added then AddANode(MyDatas);
TreeView1.Items.EndUpdate;
...
end;

3、同理,也可以用递归来完成“从最底层即叶结点开始一层层往上一层按比例累计计算一些金额”
procedure CalacANodeMoney(aNode: TTreeNode); //计算一个结点的Money
var
aChild: TTreeNode;
aData, cData: TMyData;
scale: real;
begin
aData := aNode.Data;
Case (aNode.Level) of //根据所在等级定获利比例
0: scale := 0.5
1: scale := 0.4
2: scale := 0.3
3: scale := 0.2
...
end;
aChild := aNode.GetFirstChild; //找子结点
while aChild <> nil do
begin
if aChild.HasChild then CalacANodeMoney(aChild); //如有子结点有下级则先计算下级的Money
aData.Money := aData.Money + TMyData(aChild.Data).Money * scale; //计算Money
aChild := aChild.GetNextSibling;
end;
end;

procedure CalacMoney
var
aNode : TTreeNode;
aData : TMyData;
begin
aNode := TreeView1.Items.GetFirstNode;//找到第一个顶结点
while aNode <> nil do
begin
if aNode.HasChild then CalacANodeMoney(aNode); //计算Money
aNode := aNode.GetNextSibling; //找下一个顶结点
end;
end;

4、接下来“要维护这棵树,就是需增删改这张表”,太简单了,就不用再写了吧。
 
看看DELPHI中TREEVIEW的结构对你有帮助,在TREEVIEW如何定位一个接点,一个是
ID,一个是LEVEL,对下面的树
n1----n2-----n3
n4
n5-----n6
你存储的数据应该是
ID LEVEL OTHERINFORMATION
1 1 N1
2 2 N2
3 3 N3
4 2 N4
5 2 N5
6 3 N6
你用它来生成一棵树不难,也好操作
 
chenby:如果还想接着讨论请定期提前自己的帖子,如果不想继续讨论请结束帖子。
 
多人接受答案了。
 
后退
顶部