用十字链表?不至于吧... 十字链表是用来存储稀疏矩阵的,不能表示网络中节点互连的
情况。
如果你用十字链表的初衷是为了方便的用行和列进行索引定位的话,我觉得还不如用二维
数组——因为机房中的电脑不会很稀疏,用数组的话空间浪费很少,并且索引速度还可以提
高两个数量级。如果仅仅要表示节点之间的连接信息,我觉得用复合的List就可以了:
type
TServer=class;
TLink=class
private
FServers:array[0..1]of TServer;
//连线的两个端点
function GetServer(index: Integer): TServer;
public
property Servers[index:Integer]:TServer read GetServer;
constructor Create(S1,S2:TServer);
end;
TServer=class
private
FLinks:TList;
//存放与之连接的连线列表
procedure AddLink(Link:TLink);
procedure DelLink(Link:TLink);
function GetLink(index: Integer): TLink;
function GetLinkCount: Integer;
public
Location:TPoint;
property Links[index:Integer]:TLink read GetLink;
property LinkCount:Integer read GetLinkCount;
procedure ClearLink;
constructor Create;
destructor Destroy;
override;
end;
TServers=class
private
FServers:TList;
FLinks:TList;
function GetServer(index:Integer):TServer;
function GetLink(index:Integer):TLink;
function GetLinkCount: Integer;
function GetServerCount: Integer;
public
property Servers[index:Integer]:TServer read GetServer;
default;
property Links[index:Integer]:TLink read GetLink;
property ServerCount:Integer read GetServerCount;
property LinkCount:Integer read GetLinkCount;
procedure AddServer(Loc:TPoint);
procedure Delse
rver(Server:TServer);
procedure LinkServer(S1,S2:TServer);
procedure Delse
rverLink(S1,S2:TServer);
procedure DelLink(Link:TLink);
procedure ClearServer;
procedure ClearLink;
constructor Create;
destructor Destroy;
override;
end;
{ TLink }
constructor TLink.Create(S1, S2: TServer);
begin
FServers[0]:=S1;
FServers[1]:=S2;
end;
function TLink.GetServer(index: Integer): TServer;
begin
if (index>=Low(FServers)) and (index<=High(FServers)) then
Result:=FServers[index]
else
Result:=nil;
end;
{ TServer }
procedure TServer.AddLink(Link: TLink);
begin
if FLinks.IndexOf(Link)=-1 then
FLinks.Add(Link);
end;
procedure TServer.ClearLink;
begin
FLinks.Clear;
end;
constructor TServer.Create;
begin
FLinks:=TList.Create;
end;
procedure TServer.DelLink(Link: TLink);
var
i:Integer;
begin
i:=FLinks.IndexOf(Link);
if i>=0 then
FLinks.Delete(i);
end;
destructor TServer.Destroy;
begin
FLinks.Free;
inherited;
end;
function TServer.GetLink(index: Integer): TLink;
begin
Result:=TLink(FLinks[index]^);
end;
function TServer.GetLinkCount: Integer;
begin
Result:=FLinks.Count;
end;
{ TServers }
procedure TServers.AddServer(Loc: TPoint);
var
Server:TServer;
begin
Server:=TServer.Create;
Server.Location:=Loc;
FServers.Add(Server);
end;
procedure TServers.ClearLink;
var
i:Integer;
begin
for i:=0 to FLinks.Count-1do
TLink(FLinks).Free;
FLinks.Clear;
for i:=0 to FServers.Count-1do
TServer(FServers).ClearLink;
end;
procedure TServers.ClearServer;
var
i:Integer;
begin
for i:=0 to FLinks.Count-1do
TLink(FLinks).Free;
FLinks.Clear;
for i:=0 to FServers.Count-1do
TServer(FServers).Free;
FServers.Clear;
end;
constructor TServers.Create;
begin
FServers:=TList.Create;
FLinks:=TList.Create;
end;
procedure TServers.DelLink(Link:TLink);
begin
with Linkdo
begin
Servers[0].DelLink(Link);
Servers[1].DelLink(Link);
end;
Link.Free;
FLinks.Remove(Link);
end;
procedure TServers.Delse
rver(Server: TServer);
var
i,index:Integer;
begin
index:=FServers.IndexOf(Server);
if index>=0 then
begin
for i:=FLinks.Count-1do
wnto 0do
begin
with TLink(FLinks[index])do
if (Servers[0]=Server) or (Servers[1]=Server) then
DelLink(TLink(FLinks[index]));
end;
Server.Free;
FServers.Delete(index);
end;
end;
procedure TServers.Delse
rverLink(S1, S2: TServer);
var
i:Integer;
begin
for i:=FLinks.Count-1do
wnto 0do
begin
with TLink(FLinks)do
if ((Servers[0]=s1) and (Servers[1]=s2)) or ((Servers[0]=s2) and (Servers[1]=s1))then
begin
DelLink(TLink(FLinks));
break;
end;
end;
end;
destructor TServers.Destroy;
begin
ClearLink;
ClearServer;
FServers.Free;
FLinks.Free;
inherited;
end;
function TServers.GetLink(index: Integer): TLink;
begin
Result:=TLink(FLinks[index]);
end;
function TServers.GetLinkCount: Integer;
begin
Result:=FLinks.Count;
end;
function TServers.GetServer(index: Integer): TServer;
begin
Result:=FServers[index];
end;
function TServers.GetServerCount: Integer;
begin
Result:=FServers.Count;
end;
procedure TServers.LinkServer(S1, S2: TServer);
var
Link:TLink;
i:Integer;
begin
for i:=FLinks.Count-1do
wnto 0do
//防止重复连接
begin
with TLink(FLinks)do
if ((Servers[0]=s1) and (Servers[1]=s2)) or ((Servers[0]=s2) and (Servers[1]=s1))then
exit;
end;
Link:=TLink.Create(S1,S2);
FLinks.Add(Link);
S1.AddLink(Link);
S2.AddLink(Link);
end;
使用例子:
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
with TServers.Createdo
begin
AddServer(Point(1,2));
AddServer(Point(5,9));
AddServer(Point(3,6));
AddServer(Point(7,0));
AddServer(Point(7,4));
AddServer(Point(2,8));
LinkServer(Servers[0],Servers[1]);
LinkServer(Servers[0],Servers[2]);
LinkServer(Servers[1],Servers[2]);
LinkServer(Servers[3],Servers[1]);
LinkServer(Servers[4],Servers[5]);
LinkServer(Servers[5],Servers[0]);
LinkServer(Servers[4],Servers[2]);
DelLink(Links[2]);
Delse
rver(Servers[4]);
Memo1.Lines.Clear;
Memo1.Lines.Add('--Servers--');
for i:=0 to ServerCount-1do
with Serversdo
Memo1.Lines.Add(Format('Server%d: (%d,%d) LinkCount: %d',[i,Location.X,Location.Y,LinkCount]));
Memo1.Lines.Add('--Links--');
for i:=0 to LinkCount-1do
with Linksdo
Memo1.Lines.Add(Format('Link%d: (%d,%d)--(%d,%d)',[i,
Servers[0].Location.X,Servers[0].Location.Y,
Servers[1].Location.X,Servers[1].Location.Y]));
Free;
end;
end;