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);