Спасибо за замечания.
Да я просто чтоб не заморачиваться - в дельфи написал, потом выдергал код (ХЕ3, обратите внимание на цикл while, как она его забавно скомпилировала).
Вот эту вот херь:
Код:
//type
// // двусвязный список
// PMemPtrItem = ^TMemPtrItem;
// TMemPtrItem = packed record
// Left,
// Right: PMemPtrItem;
// Data: Pointer;
// end;
//
// //
// function InsertItem(const AParent: PMemPtrItem;
// const AData: Pointer): PMemPtrItem; cdecl;
// begin
// Result := PMemPtrItem(LocalAlloc($40, SizeOf(TMemPtrItem)));
// Result^.Left := nil;
// Result^.Right := nil;
// Result^.Data := AData;
//
// if AParent <> nil then
// begin
// Result^.Left := AParent;
//
// if AParent^.Right <> nil then
// begin // вставка
// Result^.Right := AParent^.Right;
// AParent^.Right^.Left := Result;
// end else
// begin // добавление
// Result^.Right := nil;
// end;
//
// AParent^.Right := Result;
// end;
// end;
//
// // чистка слева направо
// procedure ClearItems(const AFirst: PMemPtrItem); cdecl;
// var
// i, j: PMemPtrItem;
// begin
// if AFirst = nil then
// Exit;
//
// i := AFirst;
// while i <> nil do
// begin
// VirtualFree(i^.Data, 0, MEM_RELEASE);
//
// j := i^.Right;
// LocalFree(integer(i));
// i := j;
// end;
// end;
//
// // считаем, что данные там уникальные
// // тоже слева направо ищем
// // ф-я возвращает первую запись из всего списка
// function RemoveByData(const AFirst: PMemPtrItem;
// const AData: Pointer): PMemPtrItem; cdecl;
// var
// i: PMemPtrItem;
// begin
// if AFirst = nil then
// Exit(nil);
//
// i := AFirst;
// Result := AFirst;
//
// while i <> nil do
// begin
// if i^.Data = AData then
// begin
// if i = AFirst then
// begin
// Result := i^.Right;
// Result^.Left := nil;
// end else
// begin
// if i^.Left <> nil then
// i^.Left^.Right := i^.Right;
//
// if i^.Right <> nil then
// i^.Right^.Left := i^.Left;
// end;
// // удаляем
// VirtualFree(i^.Data, 0, MEM_RELEASE);
// LocalFree(integer(i));
//
// Exit;
// end;
//
// i := i^.Right;
// end;
// end;