Помощь - Поиск - Пользователи - Календарь
Полная версия: Стек и очередь
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Aleks
Задание: Составить программу, которая из кольцевого списка из n элементов удаляет в порядке просмотра кольца каждый k-й элемент до тех пор, пока в списке не останется один элемент. Распечатать номера удаленных элементов.

в некоторых случаях прога глючит т.е., если внести числа с 1 по 9 эл. и end (всего 10 элементов)
внести шаг удаления 3
при проходе в некоторых случаях отображаются "левые" элементы - "J 1 F" , " "

при вводе 4 эл. и end (всего 5 элементов), шаг 3
Error 204: Invalid pointer operation. -> dispose( r ); (стр.4 снизу)

я думаю что не правильно сделал удаление из кольцевого списка, из-за чего и появляются ошибки: Error 204: Invalid pointer operation , или неизвестные элементы

Подскажите плиз

Код
uses Crt, WinDos;

type
 {Указатель на элемент списка}
 PTR=^Sp;
 {Тип данный для записи элемента двусвязного списка}
 Sp=record
   inf: String;{Данные}
   L1: PTR;  {Указатель на следующий элемент списка}
   L2: PTR;  {Указатель на предыдущий элемент списка}
 end;

var
 k: PTR;  {Указатель текущего элемента списка}
 f: PTR;  {Указатель начального элемента списка}
 r: PTR;  {Указатель конечного элемента списка}
 i,j: PTR;
 n: Integer; {Количество}
 ii,kk: Integer;
 Delt: Boolean;

procedure NewSpisok; {Создаем спиок}
begin
 New(k); k^.L1:=nil; k^.L2:=nil;
 write('Введите следущий элемент списка ');Readln(k^.inf);
 f:=k;   r:=k;
 while k^.inf<>'end' do
 begin
   j:=k;  new(k);
   write('Введите следущий элемент списка (или end) ');
   Readln(k^.inf);
   k^.L1:=nil;  k^.L2:=j;
   j^.L1:=k;
   r:=k;
   inc(n);
 end;
 {Замыкаем список}
 r^.L1:=f;
end;

procedure DeleteK;  {удаляем k-ый элемент}
begin
 if ii=kk then
 begin
   writeln('Удаляем элемент ',r^.inf, ' - ',ii,'-ый  элемент');
   j:=r^.L1;  if j<>nil then j^.L2:=r^.L2;
   i:=r^.L2;  if i<>nil then i^.L1:=r^.L1;
   dispose(r);
   if j<>nil then r:=j else r:=i;
   dec(n);
   ii:=0;
   Delt:=true;
 end;
end;

begin
 clrscr;
 writeln('Количество свободной памяти  ',memavail);

 n:=0;   {Количество элементов в списке}
 NewSpisok;   {Создаем список}
 write('k=');readln(kk); {указываем шаг}
 ii:=0;
 writeln('Начинаем обход списка');
 Delt:=false;
 {Пока не остался один элемент}
 while n<>0 do
 begin
   {Если этот и слежующий элемент непустые , переходим к следующему}
   if (r<>nil) and (r^.L1<>nil) and not Delt then
   begin
     r:=r^.L1;
   end;
   Inc(ii);
   writeln('Смотрим элемент ',r^.inf,' - ',ii,'-ый элемент');
   if Delt then Delt:=false;
   DeleteK;  {Если попался k-ый элемент , удаляем и печатаем номер}
 end;
 writeln('Остался элемент ',r^.inf);
 dispose (r);

 writeln('Количество свободной памяти  ',memavail);
 readln;
end.
volvo
Aleks, я тебе на параллельном форуме подсказал, но теперь я полностью изменю структуру программы. Вот так будет лучше:
uses Crt;

type
PList = ^TList;
TList = record
inf: string;
prev, next: PList;
end;

var
pos, count: integer;

function MakeList(var head: PList): integer;
var
s: string;
last, p: PList;
count: integer;
begin
head := nil; last := nil;
count := 0;
repeat

write('enter the element: '); readln(s);

new(p); inc(count);
with p^ do begin
inf := s;
next := nil; prev := last;
end;
if head = nil then head := p
else last^.next := p;

last := p


until s = 'end';
last^.next := head;
head^.prev := last;

MakeList := count - 1;
end;

function DeleteItem(p: PList; every: integer): plist;
begin
repeat

p := p^.next;
inc(pos); if pos > count then pos := 1;

if p^.inf <> 'end' then dec(every);

until every = 1;
p^.next^.prev := p^.prev;
p^.prev^.next := p^.next;
DeleteItem := p^.next;

dispose(p);
end;

procedure PrintList(head: PList);
begin
while head^.inf <> 'end' do
head := head^.next;
head := head^.next;

while head^.inf <> 'end' do begin
write(head^.inf:5);
head := head^.next;
end;
writeln;
end;

var
pt, root: PList;
every: integer;
begin
count := makelist(root);
printlist(root);
writeln;

every := 3; pos := 1;
pt := root;
repeat
pt := DeleteItem(pt, every);
printlist(pt);
writeln('#', pos:3, ' was deleted ...');
writeln;
dec(count);
until count = 1;
end.
yes2.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.