Помощь - Поиск - Пользователи - Календарь
Полная версия: Задача на ссылочные типы данных
Форум «Всё о Паскале» > 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
Спасибо огромное! Тема первая тяжелая в паскале... Я постараюсь разобраться
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.