求树的结点移动的算法(100分)

  • 主题发起人 主题发起人 hzyood
  • 开始时间 开始时间
H

hzyood

Unregistered / Unconfirmed
GUEST, unregistred user!
求一树的结点的移动算法
数据库表
结点ID(int) 结点编号(varchar(10)), 结点名称(vchar(100))
1 01 a
2 0101 aa
3 0102 aaa
4 010101 aa1
5 010102 aa2
要求: 建成树后至少结点(包括其子结点)能够在同级间改变结点排列顺序(就是改变结点及其子结点编号) 算法! (最好是鼠标拖动方式)

 
例如将0101 该为 0103
可用以下语句实现
Update 表1 Set 结点编号 = '0103' + SubString( 结点编号,5,len( 结点编号) - 5) Where 结点编号 like '0101%'
其中 5 = len('0101') + 1
 
但如果有子结点呢,有没有更好的方法呀
 
用递规,遍历整个树枝,逐个修改节点编号。
 
楼主:
你有没有去试过?
 
procedure TForm1.TVDragDrop(Sender, Source: TObject;
X, Y: Integer);
var
TargetNode, SourceNode: tTreenode;
begin
TargetNode := TV.GetNodeAt(x,y);
SourceNode := TV.Selected;
TV.Items.begin
Update;
try
CopyNodeUnder(TV, SourceNode, TargetNode);
TV.Selected := TargetNode;
finally
TV.Items.EndUpdate;
end;
end;
procedure TForm1.TVDragOver(Sender, Source: TObject;
X, Y: Integer;
State: TDragState;
var Accept: Boolean);
var
TargetNode,SourceNode: tTreeNode;
begin
TargetNode:=TV.GetNodeAt(x,y);
if (Source = Sender) and (TargetNode <> nil) then
begin
Accept:=true;
SourceNode := TV.Selected;
while (TargetNode.Parent <> nil) and (TargetNode <> SourceNode)do
TargetNode := TargetNode.Parent;
if (TargetNode = SourceNode) then
Accept := False;
end else
Accept := False;
end;

procedure TForm1.CopyNodeUnder(const TreeView: TTreeview;
const SourceNode,
TargetNode: tTreeNode);
var
NewNode: tTreeNode;
i: Integer;
TargetParent: Integer;
begin
with dmData.quSQLdo
begin
Close;
SQL.Text := 'select id from department where name like ''' + TargetNode.Text + '''';
Prepared := True;
Open;
TargetParent := Fields[0].AsInteger;
Prepared := False;
Close;
end;
ExecSQL('update department set parent = ' + IntToStr(TargetParent) + ' where name like ''' + SourceNode.Text + '''');
NewNode := TreeView.Items.AddChildFirst(TargetNode, '');
NewNode.Assign(SourceNode);
for i := SourceNode.count - 1do
wnto 0do
CopyNodeUnder(TreeView, SourceNode.Item, NewNode);
TreeView.Items.Delete(SourceNode);
end;

procedure TForm1.ExecSQL(const S: String);
begin
with dmData.quSQLdo
begin
Close;
SQL.Text := S;
Prepared := True;
ExecSQL;
Prepared := False;
Close;
end;
end;

 
to (来自:liuchengr,)你说的方法能行,是我最初也想用的方法!
 
接受答案了.
 
后退
顶部