unit LinkList;
//******************************************************************************
// Данный модуль содержит объект для работы со связным списком (очередью)
// редакция 1.0.0.4
// дата последних исправлений 14/09/2006
// (c) KAN
//******************************************************************************
interface
uses KANsConverts;
//тип связный список
Type
TLinkList = ^RLinkList; // ссылка на тип элемента очереди
RLinkList = Record //тип элемента очереди
id : integer;
name: string;
next: TLinkList;
end;
TQueue = Record //указатель на начало и конец очереди
Head : TLinkList;
Tail : TLinkList;
end;
//объект для работы с двухсвязным списком
Type CTLinkList = Class
public
Constructor Create;
Destructor Destroyer;
Procedure ClearAll; //очищаем очередь
Procedure AddItem (id : integer; name : string); //добавлеяем элемент в конец очереди
Function SearchItem (id : integer) : string; //ищим элемент по id
Function SearchItemByName (name : string) : integer; //ищим элемент по имени
Function GetAllItemID: TIntArray; //возвращает спискок ID`ов
private
Count : integer; //кол-во элементов в очереди
Queue : TQueue; //начало и конец очереди
published
property ListLen: integer read Count; //кол-во элементов в очереди
property GetQueue : TQueue read Queue; // сама очередь
end;
implementation
//------------------------------------------------------------------------------
Constructor CTLinkList.Create;
//todo:добавить хэширование, при этом указывать кол-во элементов если (-1) то без хэширования...
begin
//создаём пустой связный списк - очередь
Queue.Head:=nil;
Queue.Tail:=nil;
Count:=0;
end;
//------------------------------------------------------------------------------
Procedure CTLinkList.ClearAll; //очищаем очередь
Var ListItems : TLinkList;
begin
if Queue.Head <> nil then
begin
ListItems:=Queue.Head; // смотрим список с головы
repeat
if ListItems^.next <> nil then Queue.Head:=ListItems^.next; // узнаем следующий элемент
Dispose(ListItems); // удадяем голову
ListItems:=Queue.Head;
dec(Count); // уменьшаем счетчик
until Count <= 0; //Queue.Head = nil; // повторяем пока ничего не останится
end; //if
Queue.Head:=nil;
Queue.Tail:=nil;
Count:=0;
end;
//------------------------------------------------------------------------------
Destructor CTLinkList.Destroyer;
begin
ClearAll;
end;
//------------------------------------------------------------------------------
Procedure CTLinkList.AddItem (id : integer; name : string); //добавлеяем элемент в конец очереди
Var ListItems : TLinkList;
begin
new(ListItems); //отводим памяти кусочек
ListItems^.id:=id; //заполняем все поля
ListItems^.name:=name;
ListItems^.next:=nil; //следующего элемента пока нет
if Queue.Head = nil //если очередь былла пустой,
then Queue.Head := ListItems //то новый элемент будет головой
else Queue.Tail^.next := ListItems;//иначе хвостом
inc(Count); //увеличивам счетчик кол-во элементов в очереди
Queue.Tail:= ListItems; // приписываем элемент в хвост
end;
//------------------------------------------------------------------------------
Function CTLinkList.SearchItem (id : integer) : string; //ищим элемент по id
Var ListItems : TLinkList;
Resultat : String;
NeedExit : Boolean;
begin
Resultat:=''; //в случаи чего вернем пустую строку
if Queue.Head <> nil then // проверяем очередь на пустоту
try
ListItems:=Queue.Head; // смотрим список с головы
NeedExit:=False; //снимаем признак выхода
repeat
begin
if ListItems^.id=id then //а если наши нужный id...
begin
Resultat:= ListItems^.name; // запоминаем найденый результат
NeedExit:=True; //устанавливаем признак выхода
end;
ListItems:=ListItems^.next; // узнаем следующий элемент
end;
until ((ListItems = nil) or (NeedExit)); // повторяем пока ничего не останится или нет признака выхода
finally
SearchItem := Resultat;
end; //finally
end;//Function
//------------------------------------------------------------------------------
Function CTLinkList.SearchItemByName (name : string) : integer; //ищим элемент по имени
Var ListItems : TLinkList;
Resultat : integer;
NeedExit : Boolean;
begin
Resultat:=-1; //в случаи чего вернем пустую строку
if Queue.Head <> nil then // проверяем очередь на пустоту
try
ListItems:=Queue.Head; // смотрим список с головы
NeedExit:=False; //снимаем признак выхода
repeat
begin
if ListItems^.name=name then //а если наши нужный name...
begin
Resultat:= ListItems^.id; // запоминаем найденый результат
NeedExit:=True; //устанавливаем признак выхода
end;
ListItems:=ListItems^.next; // узнаем следующий элемент
end;
until ((ListItems = nil) or (NeedExit)); // повторяем пока ничего не останится или нет признака выхода
finally
SearchItemByName := Resultat;
end; //finally
end;//Function
//------------------------------------------------------------------------------
Function CTLinkList.GetAllItemID: TIntArray; //возвращает спискок ID`ов
Var ListItems : TLinkList;
Resultat : integer;
lResultArray: TIntArray;
begin
Resultat:=0;
SetLength(lResultArray, Count);
if Queue.Head <> nil then // проверяем очередь на пустоту
try
ListItems:=Queue.Head; // смотрим список с головы
repeat
begin
lResultArray[Resultat]:= ListItems^.id; // запоминаем
inc(Resultat);
ListItems:=ListItems^.next; // узнаем следующий элемент
end;
until (ListItems = nil); // повторяем пока ничего не останится или нет признака выхода
Альтернативой TStringlist является связный список строк, реализованный в виде объекта CTLinkList.
Комментарии и вопросы
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.