IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

 
 Ответить  Открыть новую тему 
> Динамические структуры данных, Читаю FAQ и не могу понять...
Бродяжник
сообщение 7.06.2005 8:03
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 206
Пол: Мужской

Репутация: -  3  +


Бьюсь над созданием списка с возможностью удаления элементов из середины. Вспомнил про FAQ на любимом форуме, полез туда. Читаю:
Цитата
Предположим, что надо удалить элемент, расположенный после элемента, на который указывает ссылка q.

{удаление элемента из середины списка после q^}
Procedure Del (Var q: point);
Var r: point;
Begin
 r:=q^.Next;
 q^.Next:=q^.Next;
 r^.Next:=nil
End;

Как это работает?! :o
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Altair
сообщение 7.06.2005 8:29
Сообщение #2


Ищущий истину
******

Группа: Модераторы
Сообщений: 4 824
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


опечатка...
вместо
q^.Next:=q^.Next;
надо конечно
 q^.Next:=q^.Next^.next;

если что, вот тебе тест ...

(здесь модуль strlist это из FAQ"a, только с эмулированием шаблонов smile.gif )
Uses wincrt,strlist;
var
 l:tlist;

Procedure Del (Var q: Tlist);
Var r: Tlist;
Begin
 r:=q^.Next;
 q^.Next:=q^.Next^.next;
 r^.Next:=nil
End;

Function getp(l:tlist):tlist;
begin
 while (l<>nil) and(l^.info<>'3dffg') do l:=l^.next;
 getp:=l;
end;
procedure listprint(l:tlist);
begin
 while (l<>nil) do
  begin
  writeln(l^.info);
  l:=l^.next;
  end;
end;
var
 d:tlist;
begin
 BListinit(l);
 BListAddFirst(l,'1dfg');
 BListAddFirst(l,'2abc');
 BListAddFirst(l,'3dffg');
 BListAddFirst(l,'4dsfdfg');
 writeln('---------1-----------');
 listprint(l);
 d:=getp(l);
 del(d);
  writeln('---------2-----------');
 listprint(l);

end.



UNIT StrList;
INTERFACE
Type
 TElem = string;

 TList = ^TNode;
 TNode = record
	  Info: TElem;
	  Next: TList
	 end;
{$I List.pas}

end.

list.pas - из FAQ'a
{------------------------------------------------------------------|
| процедуры и функции у которых в названии B -без заглавного звена |
| процедуры и функции у которых в названии Z - c заглавным звеном  |
|------------------------------------------------------------------}
{Инициализация}
Procedure BListInit(var L: TList);
{Добавление в голову}
Procedure BListAddFirst(var L: TList; E:TElem);
{del}
Function  BListDelEleml(var L: TList; E: TElem): boolean;
{max}
Function  BListGetMax(A: TList): string;
Function  BListGetFio(A: TList;s:string): string;
{Добавление в хвост}
Procedure BListAddLast(var L: TList; E: TElem);
{переворачивание}
Procedure BListInvert(var L: TList);
{Очистка}
Procedure ListClear ( var L: TList );


{------------------------------------------------------------}
IMPLEMENTATION
{ 1. Инициализация списка }
{Список без заглавного звена}
Procedure BListInit(var L: TList);
begin
 L:= nil
end;
{2. Добавление элемента в начало списка}
Procedure BListAddFirst(var L: TList; E:TElem);
var
 N: TList;
Begin
 new(N);
 N^.Info:=E;
 N^.Next:=L;
 L:=N
end;


{обавление элемента в конец списка }
{ Список без заглавного звена }
procedure  BListAddLast(var L: TList; E: TElem);
var
 N: TList; { добавляемое звено списка }
 { вспомогательный указатель для }
 { поиска последнего элемента списка }
 P: TList;
Begin
 new(N);
 N^.Info :=E;
 N^.Next :=nil;
 if L= nil then L:=N else
 begin
  { поиск последнего элемента списка }
  P:=L;
  while P^.Next <> nil do P:=P^.Next;
  {добавление в список нового звена }
  P^.Next:=N
 end
End;

{ 4. Удаление первого вхождения элемента Е в список L }
{ Результат функции: }
{ true - элемент найден и удален }
{ false - злемент в списке не найден }
{ Список без заглавного звена. Решение 1 }
function BListDelEleml(var L: TList; E: TElem): boolean;
var
 N: TList; { указатель на удаляемое из списка звено }
 { вспомогательный указатель для поиска звена списка.}
 { предшествующего удаляемому }
 P: TList;
 { признак: найден ли элемент Е }
 { в списке ? }
 found: boolean;
begin
 found:=false;
 if L<>nil then
 { если список не пуст }
 if L^.Info =E then { если первое звено является удаляемым }
 begin
  found:=true;
  { запоминаем указатель на }
  { удаляемое звено }
  N:=L;
  L:=L^.Next; { удаляем звено из списщ-}
  dispose(N) { освобождаем память }
 end else
 begin
  { ищем звено. предшествующее удаляемому}
  P:=L;
  while not found and (P^.Next <> nil) do
  if P^.Next^.Info = E then found:=true
  else P := P^.Next;
  if found then
  { если найдено удаляемое звено}
  begin
   { запоминаем указатель }
   { на удаляемое звено }
   N := P^.Next;
   { удаляем звено из списка }
   P^.Next := N^.Next;
   { освобождаем память }
   dispose(N)
  end
 end;
 BListDelEleml:=found
end;

Function  BListGetMax(A: TList): string;
var
 t:telem;
begin
 t:=a^.info; {!!!}
 while A <> nil DO
 begin
   A := A^.Next;
   if a^.info>t then t:=a^.info;
 end;
 BListGetMax:=t;
end;

Function  BListGetFio(A: TList;s:string): string;
begin
 while A <> nil DO
 begin
   A := A^.Next;
   if a^.info=s then blistgetfio:=a^.info;
 end;
end;
{ 5. Переворот списка }
{ Список без заглавного звена }
procedure BListInvert(var L: TList);
var
 H: TList; { вспомогательный указатель }
 P: TList; { указатель на обработанный элемент списка }
begin
 P := nil;
 while L<>nil do
 begin
  {( запоминаем указатель на следующий )}
  H := L^.Next;
  {( теперь следующий за текущим будет звено Р )}
  L^.Next := P;
  {( текущий становится предыдущим )}
  {( для следующего шага )}
  P := L;
  {( переиещаеися к следующеиу элементу списка )}
  L:=H
 end;
 L :=P { самый последний становится первым }
end;

{ 7. Удаление всех элементов списка }
procedure ListClear ( var L: TList );
var
 N: TList; { указатель на удаляемое звено списка }
begin
 while L <> nil do
 begin
  N :=L;
  L:=L^.Next;
  dispose(N)
 end
end;


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
hiv
сообщение 7.06.2005 8:53
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 660
Пол: Мужской
Реальное имя: Михаил

Репутация: -  11  +


Лучше так сделать:
{удаление элемента из середины списка после q^}
Procedure Del (Var q: point);
Var r: point;
Begin
 r:=q^.Next;
 if r<>nil then 
 begin
   q^.Next:=r^.Next;
   Dispose( r );
 end;
End;


Сообщение отредактировано: hiv - 7.06.2005 8:53


--------------------
Никогда не жадничай. Свои проблемы с любовью дари людям!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.06.2005 9:09
Сообщение #4


Гость






А можно вопрос? ЗАЧЕМ??? Перебор какой-то получается, "удалить следующий за данным элемент" ... blink.gif Ну, так удаляйте:
Procedure DeleteAfter(Var q: point);
begin
  DeleteItem(q^.next);
end;
 К началу страницы 
+ Ответить 
Бродяжник
сообщение 7.06.2005 9:10
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 206
Пол: Мужской

Репутация: -  3  +


Спасибо! А то я в себе засомневался: вдруг я вижу ошибку там, где ее нет? <_<
2 Volvo
Код для DeleteItem можно глянуть?

Сообщение отредактировано: Бродяжник - 7.06.2005 9:15
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.06.2005 12:24
Сообщение #6


Гость






Цитата(Бродяжник @ 7.06.05 9:10)
Код для DeleteItem можно глянуть?

Можно конечно, только вот для НЕ ООП-списка это не пойдет. Я передаю в DeleteItem указатель на Item, который нужно удалить, и забываю про него, меня не интересует, что с этим указателем будет дальше... Подробности - здесь: ООП - Односвязный список (list.rar)
 К началу страницы 
+ Ответить 
Бродяжник
сообщение 9.06.2005 9:18
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 206
Пол: Мужской

Репутация: -  3  +


Спасибо за подсказки... но в конце концов я, наверное, сделаю что-то вроде периодической "сборки мусора", в ходе которой "живые" элементы списка будут объединяться в новый список, а старый будет удаляться.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 24.07.2025 14:59
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"