- •1 Линейные односвязные списки
- •2 Создание, просмотр и уничтожение списка
- •3 Добавление элемента в список
- •4 Перемещение элементов списка
- •Упражнения
- •5 ВсТаВка и удаление элементов списка
- •Упражнение
- •6 Поиск элемента в списке
- •7 Вставка и удаление элемента
- •Упражнение
- •Упражнения
- •8 Сортировка списка
- •9 Рекурсивные подпрограммы обработки списка
- •Упражнение
- •Упражнения
- •Упражнение
- •10 ЗаДаЧи
- •10.1 Нерекурсивные подпрограммы
- •10.2 Рекурсивные подпрограммы
- •Литература
3 Добавление элемента в список
Пример 3.1 Добавить элемент в начало списка.
procedure Add_1(var start:link; x:integer);
var q:link; {указатель на новый элемент}
begin
new(q);
q^.inf:=x;
q^.next:=start;
start:=q
end;
Пример 3.2 Добавить элемент в конец списка.
procedure Add_2(var start:link; x:integer);
var p, {указатель на текущий элемент списка}
q:link; {указатель на новый элемент}
begin
new(q);
q^.inf:=x;
q^.next:=nil;
if start=nil then start:=q
else {поиск последнего элемента списка}
begin
p:=start;
while p^.next <> nil do
p:= p^.next;
p^.next:= q
end;
end;
4 Перемещение элементов списка
Пример 4.1 Поменять местами первый и последний элементы списка. При выполнении обмена операции выделения и освобождения памяти не использовать, информационные поля не менять.
Замечание. Предполагается, что список не пуст и содержит не менее двух элементов.
procedure Change (var start:link);
var p, {указатель на текущий элемент списка}
pr:link; {указатель на предыдущий элемент}
begin
if start^.next^.next = nil then
begin {список содержит два элемента}
p:= start^.next; p^.next:= start
end
else {список содержит более двух элементов}
begin
p:=start;
while p^.next <> nil do
begin
pr:=p;
p:= p^.next
end;
p^.next:= start^.next;
pr^.next:= start
end;
start^.next:=nil; start:=p
end;
Упражнения
Указание к решению. Операции выделения и освобождения памяти не использовать, информационные поля не менять.
1) Поменять местами первый и второй элементы списка.
2) Переместить первый элемент в конец списка.
3) Переместить последний элемент в начало списка.
Пример 4.2 Инвертировать список, то есть расположить его элементы в обратном порядке, изменяя только ссылки в этом списке.
При движении от начала списка до его конца ссылки "переворачиваются" и бывший первый элемент становится последним, а бывший последний элемент – первым. Указатель списка start используется в качестве указателя на предыдущий элемент. Когда список пройден до конца, указатель start содержит адрес бывшего последнего элемента.
procedure Inverse(var start:link);
var p, {указатель на текущий элемент списка}
q:link; {указатель на следующий элемент}
begin
p:=start;
start:=nil;
while p<>nil do
begin
q:=p^.next;
p^.next:=start;
start:=p;
p:=q
end
end;
5 ВсТаВка и удаление элементов списка
Пример 5.1 Вставить в список после каждого элемента с заданным значением x новый элемент с заданным значением y.
procedure Insert(start:link; x,y:integer);
var p, {текущий указатель}
q:link; {указатель на новый элемент}
begin
p:=start;
while p<>nil do
begin
if p^.inf=x then
begin {создание и вставка нового элемента}
new(q);
q^.inf:= y;
q^.next:=p^.next;
p^.next:=q;
p:=p^.next^.next
end
else p:=p^.next
end
end;
Пример 5.2 Вставить в список перед каждым элементом с заданным значением x новый элемент с заданным значением y.
Вставка нового элемента перед элементом с указателем p (звеном p) представляет собой более сложную задачу, чем вставка после элемента:
– если первый элемент содержит заданное значение, то вставка перед ним реализуется добавлением элемента в начало списка так, как в Примере 3.1;
– для реализации вставки внутри списка необходим ещё один указатель – указатель на предыдущий элемент.
Простой прием (в [1] и [2] он назван "трюком") позволяет решить задачу вставки перед элементом.
"Трюк" состоит в том, что новый элемент вставляется после элемента со значением x (звеном p), а затем происходит обмен значениями между новым элементом и звеном p.
procedure Insert_1(start:link; x,y:integer);
var p, {текущий указатель}
q:link; {указатель на новый элемент}
begin
p:=start;
while p<>nil do
begin
if p^.inf=x then
begin
new (q);
q^.next:=p^.next; {вставка звена q после звена p}
p^.next:=q;
q^.inf:=x; {запись x в звено q вместо y}
p^.inf:=y; {запись y в звено p}
p:=p^.next^.next
end
else p:=p^.next
end
end;