СПИСОЧНЫЕ СТРУКТУРЫ

advertisement
1.СПИСОЧНЫЕ СТРУКТУРЫ
(СПИСКИ)
Описание типов данных для элементов
списка:
type pel=^elem;
elem=record
s:integer; p:pel
end;
Здесь s – содержимое, p – указатель
Описать несколько переменных-указателей:
var p1,p2,p3: pel;
Ввыделить память для элементов списка:
new(p1); new(p2);
_____________________________________
_
p1^.s:=5; p1^.p:=p2;
p2^.s:=10; p2^.p:=nil;
2.
5
p1
10
p2
5
p1
10
p2
p1^.s:=5; p1^.p:=p2;
p2^.s:=10; p2^.p:=p1;
_____________________________________
_
Ввод с клавиатуры чисел и создание из них
линейного списка. Конец ввода – число 0.
Указатель p1 – начало списка, указатель p2
– конец списка.
_________________________________
__
type pel=^elem;
elem=record s:integer; p:pel
end;
var p1,p2,p3:pel;
s: integer;
begin
p1:=nil; p2:=nil;
read(s);
while s<>0 do
3.begin new(p3);
if p1=nil then p1:=p3
else p2^.p:=p3;
p2:=p3; p2^.s:=s; p2^.p:=nil;
read(s)
end;
...
end.
_________________________________
__Вычисление суммы содержимого
элементов линейного списка:
p3:=p1; sum:=0;
while p3<>nil do
begin
sum:=sum+p3^.s;
p3:=p3^.p
end;
_______________________________________
___
Удаление всех элементов линейного списка:
while p1<>nil do
begin
p3:=p1^.p
dispose(p1);
p1:=p3
4.end;
p2:=nil;
_________________________________
__Список – стек или очередь,
указатель pb – начало списка,
pe – конец списка.
Добавление элемента со значением X в
очередь (в конец списка):
_______________________________________
_
new(pr);
pr^.s:=X; pr^.p:=nil;
if pe=nil then pb:=pr
else pe^.p:=pr;
pe:=pr;
_______________________________________
Добавление элемента со значением X в стек
(в начало списка):
_______________________________________
new(pr);
pr^.s:=X; pr^.p:=pb; pb:=pr;
if pe=nil then pe:=pr;
_______________________________________
5.Удаление элемента из очереди или стека и
копирование его значения в переменную X
(удаление с начала списка):
_______________________________________
if pb<>nil then
begin
pr:=pb; X:=pb^.s; pb:=pb^.p;
dispose(pr)
end;
_______________________________________
_
Поиск в списках
1. Поиск значения S0 путем
последовательного просмотра в линейном
списке:
_______________________________________
__
p0:=p;
while (p0<>nil)and(p0^.s<>S0) do
5.p0:=p0^.p
_______________________________________
__
Инвариант цикла (указатель p0 указывает на
i-й элемент):
6.«среди элементов списка с номерами 1, …,
i – 1 содержимое ни одного из них не равно
S0.»
_______________________________________
__
2. Поиск значения S0 в упорядоченном по
возрастанию списке:
p0:=p;
while (p0<>nil)and(p0^.s<S0) do
p0:=p0^.p;
if (p0<>nil)and(p0^.s>S0) then
p0:=nil
_______________________________
Сортировка линейных списков
pk:=nil;
while pk<>p do
begin p1:=p; p2:=p1^.p;
while p2<>pk do
begin
if p1^.s>p2^.s then begin
z:=p1^.s; p1^.s:=p2^.s;
p2^.s:=z
end;
p1:=p2; p2:=p2^.p
end;
7.pk:=p1
end
Инвариант внутреннего цикла:
1) указатель p1 – на j-й элемент списка;
2) указатель p2 – на (j + 1)-й элемент
списка;
3) j-й элемент списка имеет максимальное
содержимое (поле s) среди элементов списка
с
1-го по j-й;
4) набор значений (полей s) всех элементов
списка остается неизменным.
Инвариант внешнего цикла:
7.1) указатель pk – на (i + 1)-й элемент
списка;
2) элементы списка с (i + 1)-го по n-й –
упорядочены по возрастанию;
3) любой элемент списка с 1-го по i-й имеет
содержимое (поле s) не больше чем
содержимое элементов списка с (i + 1)-го по
последний.
Слияние двух упорядоченных по
возрастанию линейных списков
8._______________________________
________
procedure slist(var
p1,p2,p3:pel);
var p4:pel;
begin
if p1^.s<=p2^.s then
begin p3:=p1; p4:=p1; p1:=p1^.p
end
else
begin p3:=p2; p4:=p2;
p2:=p2^.p end;
{наименьший элемент перемещен в выходной
список}
while (p1<>nil)and(p2<>nil) do
{цикл, пока оба входных списка не
пусты}
if p1^.s<=p2^.s then begin
p4^.p:=p1; p4:=p1; p1:=p1^.p
end
else begin
p4^.p:=p2; p4:=p2; p2:=p2^.p
end;
{в цикле наименьший элемент – в выходной
список}
9.if p1<>nil then p4^.p:=p1
else p4^.p:=p2;
{оставшийся непустым входной список
присоединяется в конец выходного
списка}
p1:=nil; p2:=nil
end;
Процедура sortlist – рекурсивный алгоритм сортировки списков методом слияния.
p – указатель на начало входного списка.
n – количество элементов в списке.
Список перед выполнением процедуры
неупорядочен, после выполнения –полностью
упорядочен.
______________________________________
Procedure
sortlist(var
p:pel;n:integer);
var p1,p2:pel;
k,i:integer;
begin
if n>1 then begin
k:=n div 2; p1:=p;
for i:=1 to k-1 do p1:=p1^.p;
p2:=p1^.p; p1^.p:=nil; p1:=p;
10.{список разделен на две почти
одинаковые части}
sortlist(p1,k);
sortlist(p2,n-k);
{обе
части
списка
рекурсивно
отсортированы}
slist(p1,p2,p)
{обе
части
списка
объединены
слиянием}
end
end;
Перестановки в списке
В глобальном списке (указатель p).
Перестановка из n элементов. Глобальный
массив R (из n элементов) содержит признаки
включения чисел в перестановку: если R[i]=1,
то число i включено в перестановку, а если
R[i]=0, то нет.
__________________________________________
11.procedure perlist(k:integer);
var i:integer; p1:pel;
begin new(p1);
if k=1 then
begin p:=p1; p^.p:=nil end
else begin p1^.p:=p; p:=p1 end;
for i:=1 to n do
if R[i]=0 then
begin p^.s:=i; R[i]:=1;
if k=n then ВЫВОД
else perlist(k+1);
R[i]:=0
end;
p:=p^.p; dispose(p1)
end;
Вызов: p:=nil; perlist(1);
Download