在本文中,我把对链表的操作封装到一个类中,此类是单向链表,如果想做成双向列表,需要在PNode里面加入一个Pre,
指向当前指针的前一项;如果是环形链表,则需要将尾节点的Next指向头节点。原理都是类似的。一下是这个类的详细代码。
供大家参考。(DelphiXe2中实现的)
unit Unit2;
interface
uses
Winapi.Windows,System.SysUtils, System.Classes,Vcl.Forms;
type
TStudent=record
id : Integer;
StudNo : string;
StuName : string;
Age : Integer;
Sex : string;
end;
PStudent = ^TStudent;
PNode=^TNode;
TNode=record
Next : PNode; //下一个节点,如果需要双向链表,在这里加一个 Pre : PNode
data : PStudent; //数据项,也可以直接用字段来表示,这里用指针来实现
end;
TMyLinkList= class
private
FHeadNode : PNode;
FCurrNode : PNode;
FCount : Integer;
function AnalysisData(AData : string) : PNode; //解析文本数据
public
function Add(Node : PNode) : Boolean;
function Delete(Node : PNode) : Boolean;
function SearchNode(id : Integer) : PNode;
function GetAllNode : TList;
function GetHead: PNode;
function GetCurrNode: PNode;
function GetSize : Integer;
function SaveData : Boolean; //把链表数据保存为文本文件
function LoadData : Boolean; //从文本中加载链表数据
function Next : PNode;
function First : PNode;
constructor Create;
destructor Destroy; override; {析构方法}
end;
implementation
{ TMyLinkList }
constructor TMyLinkList.Create;
begin
inherited;
FHeadNode := nil;
FCurrNode := nil;
FCount := 0;
end;
destructor TMyLinkList.Destroy;
var
mList : TList;
i : Integer;
Node : PNode;
stu : PStudent;
begin
mList := GetAllNode;
for i := 0 to mList.Count-1 do
begin
Node := PNode(mList[i]);
stu := Node.data;
Dispose(stu);
Dispose(Node);
end;
mList.Clear;
mList.Free;
inherited;
end;
//新增节点,需要将下一个节点指向Nil
function TMyLinkList.Add(Node: PNode): Boolean;
begin
Inc(FCount);
if not Assigned(FHeadNode) then
begin
FHeadNode := Node;
FCurrNode := Node;
FCurrNode.Next := nil;
end else begin
FCurrNode.Next := Node;
FCurrNode := Node;
FCurrNode.Next := nil;
end;
end;
//删除节点,需要将当前节点的上一个节点找出来,然后指向当前节点的下一个节点,接着删除当前节点
function TMyLinkList.Delete(Node: PNode): Boolean;
var
i : Integer;
ANode,ADestNode : PNode;
begin
ANode := FHeadNode;
ADestNode := Node.Next;
for I := 1 to FCount do
begin
if ANode.Next = Node then
begin
Break;
end else begin
ANode := ANode.Next;
end;
end;
ANode.Next := ADestNode;
Dispose(Node);
FCount := FCount - 1;
end;
//查找节点,根据数据的主键来查找
function TMyLinkList.SearchNode(id: Integer): PNode;
var
ANode : PNode;
i : Integer;
mList : TList;
begin
Result := nil;
ANode := FHeadNode;
for I := 1 to FCount do
begin
if ANode.data.id = id then
begin
Result := ANode;
Break;
end;
ANode := ANode.Next;
end;
end;
//查询所有节点,并将节点数据装载到List里面去,此方法并非链表所必须的方法
function TMyLinkList.GetAllNode : TList;
var
i : Integer;
mList : TList;
ANode : PNode;
begin
ANode := FHeadNode;
mList := TList.Create;
for I := 1 to FCount do
begin
mList.Add(ANode);
ANode := ANode.Next;
end;
Result := mList;
end;
function TMyLinkList.GetCurrNode: PNode;
begin
Result := FCurrNode;
end;
function TMyLinkList.GetHead: PNode;
begin
Result := FHeadNode;
end;
function TMyLinkList.GetSize: Integer;
begin
Result := FCount;
end;
//获取头节点
function TMyLinkList.First: PNode;
begin
Result := nil;
if FCount=0 then Exit;
FCurrNode := FHeadNode;
Result := FCurrNode;
end;
//获取下一个节点
function TMyLinkList.Next: PNode;
begin
Result := nil;
if FCount=0 then Exit;
if FCurrNode.Next = nil then Exit;
FCurrNode := FCurrNode.Next;
Result := FCurrNode;
end;
function TMyLinkList.SaveData: Boolean;
var
mList : TList;
i : Integer;
ANode : PNode;
dataList : TStringList;
sText,sFileName : string;
begin
try
sFileName := ExtractFilePath(Application.ExeName) + 'Linklist.data';
dataList := TStringList.Create;
mList := GetAllNode;
for i := 0 to mList.Count-1 do
begin
ANode := PNode(mList[i]);
sText := Format('id=%d,StudNo=%s,StuName=%s,Age=%d,Sex=%s',[ANode.data.id,ANode.data.StudNo,ANode.data.StuName,
ANode.data.Age,ANode.data.Sex]);
dataList.Add(sText);
end;
mList.Free;
if FileExists(sFileName) then DeleteFile(sFileName);
dataList.SaveToFile(sFileName);
finally
dataList.Free;
end;
end;
function TMyLinkList.LoadData: Boolean;
var
i : Integer;
mList : TStringList;
sFileName : string;
begin
try
sFileName := ExtractFilePath(Application.ExeName) + 'Linklist.data';
mList := TStringList.Create;
if not FileExists(sFileName) then Exit;
mList.LoadFromFile(sFileName);
for i := 0 to mList.Count-1 do
begin
Self.Add(AnalysisData(mList[i]));
end;
finally
mList.Free;
end;
end;
function TMyLinkList.AnalysisData(AData: string): PNode;
var
i,j : Integer;
mList : TStringList;
sFileName : string;
Node : PNode;
Stu : PStudent;
begin
try
Result := nil;
mList := TStringList.Create;
mList.Delimiter := ',';
mList.DelimitedText := AData;
New(Node);
New(Stu);
Stu^.id := StrToInt(mList.Values['id']);
Stu^.StudNo := mList.Values['StudNo'];
Stu^.StuName := mList.Values['StuName'];
Stu^.Sex := mList.Values['Sex'];
Stu^.Age := StrToInt(mList.Values['Age']);
Node.data := Stu;
Result := Node;
finally
mList.Free;
end;
end;
end.