Помощь - Поиск - Пользователи - Календарь
Полная версия: Задача на ссылочные типы данных
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Eskel
Спасибо огромное форуму. Смог решить 2 задачи по вставке и удалению элемента при работе с динамической памятью. Вот только не пойму как решить с помощью описанных у вас процедур 2 задачи:

1)
type tip_elem=integer;
     ukaz=^dinam;
     dinam=record
       ed:tip_elem;
       next:ukaz;
     end;
.
Удалить из списка Ukaz за каждым вхождением элемента Е один элемент отличный от Е (если он есть).

2) Певая часть условия совпадает... Удалить из списка Ukaz все нули
Lapp
Цитата(Eskel @ 23.12.2008 0:59) *
1)
type tip_elem=integer;
     ukaz=^dinam;
     dinam=record
       ed:tip_elem;
       next:ukaz;
     end;
Удалить из списка Ukaz за каждым вхождением элемента Е один элемент отличный от Е (если он есть).

2) Певая часть условия совпадает... Удалить из списка Ukaz все нули

Насколько я понял, тебя затрудняет удаление элементов из списка. В этом нет ничего сложного, нужно просто завести буферный указатель и положить в него значение указателя из удаляемого элемента. Затем освободить память (либо Dispose, либо FreeMem - в зависимости, как брал), занимаемую удаляемым элментом и присвоить указателю на него значение, сохраненное в буфере.

А нахождение кандидата на удаление - это вряд ли сложно. Или тоже объяснить?
volvo
  while r <> nil do begin
    if r^.ed = E then
      if (r^.next <> nil) and (r^.next^.ed <> E) then
      begin
        t := r^.next;
        r^.next := t^.next;
        dispose(t);
      end;
    r := r^.next;
  end;

R - корень списка... Кстати, на будущее, Eskel, показывай, как заполняешь список, если уж говоришь, что реализовал...

А теперь у меня к тебе просьба: прокомментируй мою программу, пожалуйста, чтобы было ясно, понял ты ее или нет...
Eskel
Цитата
А теперь у меня к тебе просьба: прокомментируй мою программу, пожалуйста, чтобы было ясно, понял ты ее или нет...

Ну если комментировать пошагово:
Делаем цикл по элементам списка.
Сравниваем текущую фактическую часть с вводимым значением с клавы.
Ну понятно, если равно, то надо найти число отлично от Е, то тогда
t присваиваем знач ссылки r.(t видимо тоже ukaz) и меняем ссылку r на ссылку t.
Освобождаем память.
Ну и для продолжения цикла стандартно r := r^.next; ... Еще лучше я разберусь, когда сейчас попробую осуществить это все в проге.

Заполнял я список так...
 begin
  clrscr;
  h:=nil;
  writeln('vvedite kol-vo zapisey');
  readln(n);
   for i:=1 to n do begin
    write('chislo ');
    readln(e);
    addel(h,e) end;
...
...
...
procedure addel(var h:ukazat; e:tip_elem);
var p,pr:ukazat;
begin
  new(p);
  p^.ed:=e;
  p^.next:=nil;
  if h=nil then h:=p
  else begin
    pr:=h;
    while pr^.next<>nil do
          pr:=pr^.next;
    pr^.next:=p;
  end;
end; 

Eskel
Lapp, Как находить кандидата я разобрался с помощью вашей справки. Благодарю smile.gif

Но тут просто их много и я путаюсь...
Eskel
program dina;
uses crt;
type tip_elem=integer;
     ukazat=^dinam;
     dinam=record
       ed:tip_elem;
       next:ukazat;
     end;
var h:ukazat;
    e:tip_elem;
    i,n:integer;
procedure addel(var h:ukazat; e:tip_elem);
var p,pr:ukazat;
begin
  new(p);
  p^.ed:=e;
  p^.next:=nil;
  if h=nil then h:=p
  else begin
    pr:=h;
    while pr^.next<>nil do
          pr:=pr^.next;
    pr^.next:=p;
  end;
end;

procedure show(h:ukazat);
begin
  writeln('==========');
  while h<>nil do begin
    writeln(h^.ed);
    h:=h^.next;
  end;
end;

procedure delsp(var h:ukazat);
var p:ukazat;
begin
  while h<>nil do begin
    p:=h^.next;
    dispose(h);
    h:=p;
  end;
end;
procedure obr(e:tip_elem; var h:ukazat);
var r:ukazat;
begin
while r<>nil do begin
if r^.ed=e then
if (r^.next<>nil) and (r^.next^.ed<>e) then begin
h:=r^.next;
r^.next:=h^.next;
dispose(h); end;
r:=r^.next end;
end;

begin
  clrscr;
  h:=nil;
  write('vvedite kol-vo zapisey ');
  readln(n);
   for i:=1 to n do begin
    write('chislo ');
    readln(e);
    addel(h,e) end;
  show(h);
  writeln('vvedite element E');
  readln(e);
  obr(e,h);
  show(h);
  delsp(h);
  show(h);
  readln
end.

nea.gif Вот, что я пытался сделать...
volvo
Внутри Obr кто инициализировать R будет? У тебя ж там мусор...
Eskel
То есть R входящий параметр?(может я неправильно назвал). Подскажите, плиз, как эту процедуру правильно завернуть...
volvo
Ты ж все написал, только чуть-чуть поправить:

procedure obr(e:tip_elem; r:ukazat); { <--- указатель на первый элемент изменяться не может }
var h:ukazat; { для временного хранения указателя на удаляемый элемент }
begin
  while r<>nil do begin
    if r^.ed=e then
      if (r^.next<>nil) and (r^.next^.ed<>e) then begin
        h:=r^.next;
        r^.next:=h^.next;
        dispose(h);
      end;
    r:=r^.next
  end;
end;
Eskel
Спасибо! А чтобы удалять текущий элемент надо делать как у вас с помощью поиска ссылки на текущий элемент? или можно также в одной процедуре?
 procedure obr(r:ukazat);
var h:ukazat;
begin
while r<>nil do begin
if r^.ed=0 then begin
...
r:=r^.next end end; 

volvo
А вот чтобы удалять нулевой элемент, надо принять во внимание 2 вещи: во-первых, если нули начинают список, то указатель на начало списка может измениться. А во-вторых, удалять текущий элемент надо гораздо более внимательно, чем "следующий". Итого, я бы сделал твои задачи в 2-х процедурах: сначала удалить элементы после E, а потом - вот это:

procedure del_zeroes(var root: ukaz);
var
  r, t, pred: ukaz;
  delete: boolean;
begin
  while root^.ed = 0 do begin
    t := root;
    root := root^.next;
    dispose(t);
  end;

  pred := root; r := root^.next;
  while r <> nil do begin

    delete := false;
    if r^.ed = 0 then begin
      t := r;
      pred^.next := r^.next;
      delete := true
    end
    else pred := r;

    r := r^.next;
    if delete then dispose(t);

  end;
end;
Что непонятно - спрашивай...
Eskel
Спасибо огромное! Тема первая тяжелая в паскале... Я постараюсь разобраться
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.