Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Двусв_Списки МУ.doc
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
195.58 Кб
Скачать

Упражнение

Подготовить тестовые примеры и протестировать процедуру Dubl .

Пример 6.4 Удалить все элементы непустого списка с заданным значением x .

В процедуре удаления используются процедуры раздела 2.

procedure Del_x(var first, last:link; x:integer);

var p:link; {указатель на текущий элемент списка}

begin

p:=first;

while p<>nil do

if p^.inf=x then

begin

if p=first then {удаление первого элемента}

begin Del_first(first, last);

p:=first {указатель p перемещается на начало списка}

end

else

if p=last then {удаление последнего элемента}

begin Del_last(first, last);

p:=last {указатель p перемещается на конец списка}

end

else Del_p_next(p) {удаление текущего элемента}

end

else p:=p^.next;

end;

Контрольные примеры

1) Список (значения информационных полей списка): 1 3 7 1 3 5 1

а) x =1

Результат:

просмотр от первого до последнего элемента : 3 7 3 5

просмотр в обратном порядке : 5 3 7 3

б) x =2

Результат:

просмотр от первого до последнего элемента : 1 3 7 1 3 5 1

просмотр в обратном порядке : 1 5 3 1 7 3 1

2) Список из одинаковых элементов: 1 1 1 1

x =1

Результат просмотров от первого до последнего элемента и в обратном порядке – пустой список.

Пример 6.5 В каждой подпоследовательности из подряд идущих одинаковых элементов оставить один элемент (удалить дубликаты).

В процедуре удаления дубликатов используются процедура Del_last удаления последнего элемента (см. раздел 2 ) и процедура Del_next удаления внутреннего элемента, следующего за элементом с заданным адресом p .

Удаление элемента после элемента с заданным адресом

procedure Del_next(var p: link);

begin

p^.next:=p^.next^.next;

dispose(p^.next^.prev);

p^.next^.prev:=p

end;

Удаление дубликатов

procedure Del_dubl(first:link; var last:link);

begin

while first <> last do {цикл до последнего элемента}

if first^.inf = first^.next^.inf then

if first^.next=last then {удаление последнего элемента}

Del_last(first, last)

else {удаление элемента внутри списка}

Del_next(first)

else first:=first^.next;

end;

Контрольные примеры

1) Список (значения информационных полей списка): 1 1 1 2 3 3 5 5 5

Результат:

просмотр от первого до последнего элемента : 1 2 3 5

просмотр в обратном порядке : 5 3 2 1

2) Список из одинаковых элементов: 1 1 1 1

Результат просмотров от первого до последнего элемента и в обратном порядке – список из одного элемента со значением информационного поля равным 1.

Упражнение

Описать процедуру удаления дубликатов, не использующую процедуру Del_last удаления последнего элемента. Сравнить тексты и работу обеих процедур удаления дубликатов.

Пример 6.6 Удалить из списка перед первым элементом с заданным значением x один элемент, если значение удаляемого элемента отрицательно.

Если удаление невозможно, указать причину.

Алгоритм удаления элемента

Удаление невозможно,

если список пуст, или состоит из одного элемента,

или элемент с заданным значением x – первый в списке.

Если второй элемент списка имеет заданное значение x,

а значение первого элемента отрицательно, то удаляется первый элемент,

иначе организуется поиск пары элементов:

один из элементов имеет заданное значение x,

а элемент, предшествующий ему, – отрицательное значение.

Если такая пара элементов найдена, то первый элемент из этой пары (с отрицательным значением) удаляется.

Процедура Del_prev_minus решения задачи использует для удаления внутреннего элемента, предшествующего элементу с заданным адресом p, процедуру Del_prev.

Удаление элемента перед элементом с заданным адресом

procedure Del_prev(p: link);

begin

p^.prev:=p^.prev^.prev;

dispose(p^.prev^.next);

p^.prev^.next:=p

end;

procedure Del_prev_minus(var first:link; last:link;

x:integer);

var p:link; fl: boolean;

begin

if (first=nil) and (last=nil) then

writeln('список пуст')

else

if (first^.next=nil) and (first^.prev=nil) then

writeln('в списке один элемент')

else

if first^.inf=x then

writeln('элемент с заданным значением – первый')

else

begin

p:=first^.next;

if (p^.inf=x) and (first^.inf < 0) then

begin {удаление первого элемента списка}

p^.prev:=nil;

dispose(first);

first:=p

end

else

begin

fl:=true;

while (p<>nil)and fl do {поиск пары элементов}

if (p^.inf=x) and (p^.prev^.inf < 0)

then fl:= false

else p:=p^.next;

if fl then

writeln('элемент с заданным значением не найден ',

'или перед ним неотрицательный элемент')

else {пара элементов найдена}

Del_prev(p) {первый элемент из пары элементов удален}

end

end

end;

Контрольные примеры (тесты)

Нормальные тесты (пара элементов, удовлетворяющих условию, найдена, и первый из элементов этой пары удалён):

1) Список (значения информационных полей списка): -1 3 1 -7 1 0 -5 1 -4 2

а) x = 3

Результат:

просмотр от первого до последнего элемента : 3 1 -7 1 0 -5 1 -4 2

просмотр в обратном порядке : 2 -4 1 -5 0 1 -7 1 3

б) x = 1

Результат:

просмотр от первого до последнего элемента : -1 3 1 1 0 -5 1 -4 2

просмотр в обратном порядке : 2 -4 1 -5 0 1 1 3 -1

2) Список из двух элементов: -3 -1

x = -1

Результат просмотров от первого до последнего элемента и в обратном порядке – список из одного элемента со значением информационного поля равным -1.

Исключительные ситуации (удаление невозможно):

1) Пустой список.

2) В списке один элемент.

3) Список: -1 3 7 -1 0 7 1 7 -4 5

а) x = -1 Элемент с заданным значением – первый в списке.

б) x = 4 Элемент с заданным значением в списке отсутствует.

в) x = 7 Каждому элементу с заданным значением предшествует элемент с неотрицательным значением (положительным или нулевым).