{установить курсор в позицию с заданным индексом}
sllPositionAtNth(aIndex);
{вставить элемент в позицию курсора}
InsertAtCursor(aItem);
end;
function TtdSingleLinkList.Last : pointer;
begin
{установить курсор в позицию с заданным индексом}
sllPositionAtNth(pred(Count));
{вернуть данные с позиции курсора}
Result := FCursor^.slnData;
end;
function TtdSingleLinkList.sllGetItem(aIndex : longint): pointer;
begin
{установить курсор в позицию с заданным индексом}
sllPositionAtNth(aIndex);
{вернуть данные с позиции курсора}
Result := FCursor^.slnData;
end;
procedure TtdSingleLinkList.sllSetItem(aIndex : longint; aItem : pointer);
begin
{установить курсор в позицию с заданным индексом}
sllPositionAtNth(aIndex);
{если возможно удалить заменяемые данные, удалить их}
if Assigned(FDispose) and (aItem <> FCursor^.sInData) then
FDispose(FCursor^.slnData);
{заменить данные}
FCursor^.slnData := aItem;
end;
Теперь нам осталось рассмотреть еще несколько методов, которые по разным причинам реализованы в соответствие с главными принципами. Метод Add добавляет элемент в конец связного списка. Код поиска последнего узла достаточно прост и имеет смысл реализовать его в коде самого метода. В эту группу входит и метод IndexOf. Поиск заданного элемента с помощью этого метода можно организовать только в коде самого метода. После написания кода метода IndexOf реализация Remove становиться предельно простой.
Листинг 3.12. Методы Add, IndexOf и Remove
function TtdSingleLinkList.Add(aItem : pointer): longint;
var
WorkCursor : PslNode;
WorkParent : PslNode;
begin
{для увеличения быстродействия используются локальные переменные}
WorkCursor :=FCursor;
WorkParent :=FParent;
{перешли в конец связного списка}
while (WorkCursor <> nil) do
begin
WorkParent := WorkCursor;
WorkCursor := WorkCursor^.slnNext;
end;
{перенести реальный курсор}
FParent := WorkParent;
FCursor := nil;
FCursorIx := Count;
Result := Count;
{вставить элемент в позицию курсора}
InsertAtCursor(aItem);
end;
function TtdSingleLinkList.IndexOf(aItem : pointer): longint;
var
WorkCursor : PslNode;
WorkParent : PslNode;
WorkCursorIx : longint;
begin
{установить рабочий курсор на первый узел (если таковой существует)}
WorkParent := FHead;
WorkCursor := WorkParent^.slnNext;
WorkCursorIx := 0;
{идти по списку в поисках требуемого элемента}
while (WorkCursor <> nil) do
begin
if (WorkCursor^.slnData = aItem) then begin
{требуемый элемент найден; записать результат; установить реальный курсор в позицию рабочего курсора}
Result := WorkCursorIx;
FCursor := WorkCursor;
FParent := WorkParent;
FCursorIx := WorkCursorIx;
Exit;
end;
{перешли к следующему узлу}
WorkParent := WorkCursor;
WorkCursor := WorkCursor^.slnNext;
inc(WorkCursorIx);
end;
{требуемый элемент не найден}
Result := -1;
end;
procedure TtdSingleLinkList.Remove(aItem : pointer);
begin
if (IndexOf (aItem) <> -1) then
DeleteAtCursor;