Войти
ДельфинарийФорум

Связные списки в Дельфи. Есть ли элегантное решение?

#0
19:30, 6 фев. 2011

Те кто щупал Blitz3D знают что не одна программа на нем не обходиться без тамошних типов (связных списков).
Type tparticle
  Field x#,y#,life%
End type

For particles.tparticle=Each tparticle
......................
Next
и тд.

Очень удобная вещь для кучи обьектов, обычно частиц.
Вопрос: Есть ли в Дельфи средства для реализации столь же удобного связного(динамического) списка? Желательно без указателей.


#1
0:49, 7 фев. 2011

А в чем сомнения? Связный список - довольно распространенная структура данных.
Если без указателей, то через классы:
TParticle = class
  x, y, z: Single;
  next: TParticle;
end;

Наверное, если реалтзовать соответсвующий интерфейс, то и foreach заработает с ним.:)

Только неясно, чем оно удобнее скажем, массива?

#2
7:11, 7 фев. 2011

radiantor
через динамический массив не проще?
для удаления элемента заменяешь его на последний в массиве и уменьшаешь размер массива
учти что много динамически выделяемых объектов могут дать сильную фрагментацию кучи и тормоза

#3
2:45, 8 фев. 2011

Aslan
>много динамически выделяемых объектов могут дать сильную фрагментацию кучи и тормоза
Если все они одного типа и стандартный дельфевый манагер памяти, то множественные удаления/выделения объектов ничего фрагментировать и тормозить не будут.

#4
11:35, 8 фев. 2011

stopkin
разве New не проходит каждый раз по всему списку блоков в поисках свободного, подходящего размера
при большом числе блоков тормоза

#5
20:21, 8 фев. 2011

С динамическими массивами не так удобно, как в Блиц.
Блиц3Д код

For particle.tparticle=Each tparticle 

 particle.life=particle.life+1

 if particle.life>100 then delete(particle)

Next 

На Дельфи

For i:=0 to High(particle) do 
 if particle[i]<>nil
  then
   begin
      particle[i].life=particle[i].life+1;
      if particle[i].life>100 then particle[i]:=nil;
   end;
Next 
C Классами пока не понял как реализовать.
#6
21:08, 8 фев. 2011

radiantor
С динамическими массивами еще лучше )))

// скопировать массив сам в себя, умершие частицы пропустить
count:=0;
for i:=0 to High(particles) do
begin
  Inc(particles[i].life);
  if particles[i].life<=100 then 
  begin
    particles[count]:=particles[i];
    Inc(count);  
  end
end;
// сократить размер
SetLength(particles,count);
Delphi Class - вообще не используй, он распределяется только в динамической памяти, надо освобождать через Free.
Если нужны классы, используй Object
#7
21:29, 8 фев. 2011

Aslan
> С динамическими массивами еще лучше )))
> // скопировать массив сам в себя, умершие частицы пропустить
>................
> particles[count]:=particles[i];
> Inc(count);
>..................
> // сократить размер
> SetLength(particles,count);

Вот это место я не понял :-) Тут надо наоборот
> particles[i]:=particles[count];
> Dec(count);
Или я загоняюсь? (простужен я).

> Delphi Class - вообще не используй, он распределяется только в динамической
> памяти, надо освобождать через Free.
> Если нужны классы, используй Object
Спасибо за совет.

#8
6:21, 9 фев. 2011

radiantor
count - кол-во живых частиц, во время прохода мы его увеличиваем и записываем живых в тот же
массив на ту же или меньшую позицию, мертвых пропускаем

#9
23:04, 20 фев. 2011

А что по поводу TObjectsList ? Стоит юзать?

#10
7:13, 21 фев. 2011

radiantor
лучше юзай динам.массив

ДельфинарийФорум

Тема в архиве.