|
|
Linia 250: |
Linia 250: |
| == Zadanie 7 (Pierwszy wspólny element list łączących się)== | | == Zadanie 7 (Pierwszy wspólny element list łączących się)== |
| Dane są dwie listy proste (kończące się nilami) i takie że maja one element wspólny (funkcja Wspólny z poprzedniego zadania dałaby wynik true). Napisz funkcję odnajdującą pierwszy element wspólny tych list. | | Dane są dwie listy proste (kończące się nilami) i takie że maja one element wspólny (funkcja Wspólny z poprzedniego zadania dałaby wynik true). Napisz funkcję odnajdującą pierwszy element wspólny tych list. |
| | | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| {{wskazowka| 1||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
| | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka</span> |
| | <div class="mw-collapsible-content" style="display:none"> |
| Każdy wspólny element list jest tak samo odległy od końca list. Jeśli więc obliczymy długości list to możemy iść po nich równocześnie w takiej samej odległości od końca i sprawdzać czy trafiliśmy już na wspólny element czy nie. | | Każdy wspólny element list jest tak samo odległy od końca list. Jeśli więc obliczymy długości list to możemy iść po nich równocześnie w takiej samej odległości od końca i sprawdzać czy trafiliśmy już na wspólny element czy nie. |
| </div> | | </div> |
| </div> | | </div> |
| }}
| |
|
| |
|
| {{rozwiazanie| 1||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
| | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> |
| | <div class="mw-collapsible-content" style="display:none"> |
| '''function''' PierwszyWspólny(l1, l2:lista):lista; | | '''function''' PierwszyWspólny(l1, l2:lista):lista; |
| //Listy l1 i l2 maja wspólny element; szukamy pierwszego elementu wspólnego tych list | | //Listy l1 i l2 maja wspólny element; szukamy pierwszego elementu wspólnego tych list |
Linia 285: |
Linia 287: |
| ''Koszt pamięciowy'': stały | | ''Koszt pamięciowy'': stały |
| </div> | | </div> |
| </div>}} | | </div> |
|
| |
|
| {{cwiczenie| 1|pytanko 1|<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
| | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Ćwiczenie</span> |
| | <div class="mw-collapsible-content" style="display:none"> |
| Skąd wiadomo, że w ostatnim while'u l1 i l2 sa zawsze różne od nil ? | | Skąd wiadomo, że w ostatnim while'u l1 i l2 sa zawsze różne od nil ? |
| </div> | | </div> |
| </div>}} | | </div> |
|
| |
|
| == Zadanie 8 (Listy z cyklem)== | | == Zadanie 8 (Listy z cyklem)== |
To są zadania na listy.
Oglądaj wskazówki i rozwiązania __SHOWALL__
Ukryj wskazówki i rozwiązania __HIDEALL__
W poniższych zadaniach będziemy używać następujących typów:
type lista = ^el_listy;
el_listy = record
w: integer;
nast: lista;
end;
Zadanie 1 (Odwracanie listy)
Napisz procedurę Odwróć(var l:lista) odwracającą listę l.
Rozwiązanie 1
procedure Odwróć(var l:lista);
//Odwracamy listę l
var poprz, akt, pom : lista;
begin
if l <> nil then begin
poprz:=nil;
akt:=l;
while akt<>nil do begin
pom:=akt^.nast;
akt^.nast:=poprz;
poprz:=akt;
akt:=pom;
end;
end;
l:=poprz;
end;
Koszt czasowy: liniowy względem długości listy
Koszt pamięciowy: stały
Wizualizacja
Zadanie 2 (Scalanie dwóch posortowanych list)
Napisz funkcję Scal(l1,l2:lista):lista scalającą dwie posortowane niemalejąco listy l1 i l2, tak aby wynikowa lista również była posortowana niemalejąco.
Rozwiązanie
function Scal(l1,l2:lista): lista;
//Listy l1 i l2 są posortowane niemalejąco; scalamy je do jednej listy również posortowanej niemalejąco
var atrapa, akt : lista;
begin
new(atrapa);
atrapa^.nast:=nil;
akt:=atrapa;
while (l1 <> nil) and (l2 <> nil) do
if l1^.w < l2^.w then begin //jeśli l1^.w < l2^.w
akt^.nast:=l1;
akt:=akt^.nast;
l1:=l1^.nast;
end
else
if l1^.w > l2^.w then begin //jeśli l1^.w > l2^.w
akt^.nast:=l2;
akt:=akt^.nast;
l2:=l2^.nast;
end
else begin //jeśli l1^.w = l2^.w - ten else można sobie darować, i tak będzie dobrze
akt^.nast:=l1;
akt:=akt^.nast;
l1:=l1^.nast;
akt^.nast:=l2;
akt:=akt^.nast;
l2:=l2^.nast;
end;
if l1 = nil then //obsługa końcówki listy która nie jest pusta
akt^.nast:=l2
else
akt^.nast:=l1;
Scal:=atrapa^.nast;
dispose(atrapa);
end;
Koszt czasowy: liniowy względem sumy długości list
Koszt pamięciowy: stały
Wizualizacja
Ćwiczenie
Czy instrukcja atrapa^.nast:=nil jest potrzebna? W jakich przypadkach ?
Zadanie 3 (Usuwanie elementów zadanych listą)
Napisz procedurę Usuń(var l1:lista; l2:lista) która usunie z listy l1 wszystkie elementy z listy l2. Zakładamy, że listy l1 i l2 są posortowane niemalejąco.
Rozwiązanie
procedure Usuń(var l1:lista; l2:lista);
//Usuwamy z listy l1 wszystkie elementy z listy l2; zakładamy, że listy l1 i l2 są posortowane niemalejąco
var atrapa, poprz: lista;
begin
new(atrapa);
atrapa^.nast:=l1;
poprz:=atrapa;
while (l1 <> nil) and (l2 <> nil) do
if l1^.w < l2^.w then begin //jeśli l1^.w < l2^.w
l1:=l1^.nast;
poprz:=poprz^.nast;
end
else
if l1^.w > l2^.w then //jeśli l1^.w > l2^.w
l2:=l2^.nast
else begin //jeśli l1^.w = l2^.w
poprz^.nast:=l1^.nast;
dispose(l1);
l1:=poprz^.nast;
end;
l1:=atrapa^.nast;
dispose(atrapa);
end;
Koszt czasowy: liniowy względem sumy długości list
Koszt pamięciowy: stały
Wizualizacja
Ćwiczenie
Czy lista l1 musi być przekazywana przez zmienną ? W jakich przypadkach jest to konieczne ?
Zadanie 4 (Uporządkowanie elementów w liście)
Napisz procedurę Uporządkuj(var l:lista) która przestawi elementy w liście l tak by najpierw były elementy w których pole w jest ujemne, potem równe zero, a na końcu dodatnie. Dodatkowo względna kolejność elementów jednego rodzaju (dodatnich, równych zero i ujemnych) powinna być zachowana.
Rozwiązanie
procedure Uporządkuj(var l:lista);
//Ustawiamy elementy listy l tak by najpierw były elementy ujemne, potem równe zero, a na końcu dodatnie
//Osobno zbieramy elementy ujemne, dodatnie i równe zero i potem je łączymy
var atrapau, atrapaz, atrapad, u, z, d : lista;
begin
new(atrapau); u:=atrapau;
new(atrapaz); z:=atrapaz;
new(atrapad); d:=atrapad;
while l <> nil do begin
if l^.w < 0 then begin //dołączamy l do listy u
u^.nast:=l;
u:=u^.nast;
end
else
if l^.w = 0 then begin //dołączamy l do listy z
z^.nast:=l;
z:=z^.nast;
end
else begin //dołączamy l do listy d
d^.nast:=l;
d:=d^.nast;
end;
l:=l^.nast;
end; //while
d^.nast:=nil;
z^.nast:=atrapad^.nast;
u^.nast:=atrapaz^.nast;
l:=atrapau^.nast;
dispose(atrapad);
dispose(atrapaz);
dispose(atrapau);
end;
Koszt czasowy: liniowy względem długości listy
Koszt pamięciowy: stały
Wizualizacja
Zadanie 5 (Problem Józefa Flawiusza)
Napisz procedurę Flawiusz(var l:lista; k:integer), która dla danego
k > 0 i niepustej cyklicznej listy l, cyklicznie usuwa co k-ty element listy l, aż pozostanie w niej tylko jeden element. Liczenie rozpoczynamy od elementu wskazywanego przez l.
Rozwiązanie
procedure Flawiusz(var l:lista; k:integer);
//Usuwamy z listy l cyklicznie co k-ty element dopóki nie zostanie jeden element; k>0, l niepusta cykliczna
var poprz, pom: lista;
begin
poprz:=l^.nast;
while poprz^.nast <> l do poprz:=poprz^.nast; //poprz wskazuje na element poprzedzający l
while poprz <> poprz^.nast do begin //dopóki lista ma więcej niz jeden element
for i:=1 to k-1 do poprz:=poprz^.nast;
pom:=poprz^.nast;
poprz^.nast:=pom^.nast;
dispose(pom);
end;
l:=poprz;
end;
Koszt czasowy: rzędu n*k, gdzie n to długość listy
Koszt pamięciowy: stały
Zadanie 6 (Listy łączące się)
Dane są dwie listy proste (kończące się nilami). Napisz funkcję stwierdzającą czy te listy mają jakiś wspólny element (nie wartość typu integer, a element typu el_listy).
Wskazówka
Jeśli listy mają wspólny element to ostatni niepusty element l1 i ostatni niepusty element l2 muszą być takie same.
Rozwiązanie
function Wspólny(l1, l2:lista):boolean;
//Sprawdzamy czy listy proste l1 i l2 maja wspólny element
var pom1, pom2: lista;
begin
if l1=nil or l2=nil then Wspólny:=false
else begin
pom1:=l1;
while pom1^.nast <> nil do pom1:=pom1.^nast;
pom2:=l2;
while pom2^.nast <> nil do pom2:=pom2.^nast;
Wspólny:=(pom1=pom2);
end;
end;
Koszt czasowy: liniowy względem sumy długości list
Koszt pamięciowy: stały
Zadanie 7 (Pierwszy wspólny element list łączących się)
Dane są dwie listy proste (kończące się nilami) i takie że maja one element wspólny (funkcja Wspólny z poprzedniego zadania dałaby wynik true). Napisz funkcję odnajdującą pierwszy element wspólny tych list.
Wskazówka
Każdy wspólny element list jest tak samo odległy od końca list. Jeśli więc obliczymy długości list to możemy iść po nich równocześnie w takiej samej odległości od końca i sprawdzać czy trafiliśmy już na wspólny element czy nie.
Rozwiązanie
function PierwszyWspólny(l1, l2:lista):lista;
//Listy l1 i l2 maja wspólny element; szukamy pierwszego elementu wspólnego tych list
var dl1, dl2, i: integer;
pom1, pom2: lista;
begin
dl1:=0; pom1:=l1;
while pom1 <> nil do begin //liczymy długość l1
dl1:=dl1+1;
pom1:=pom1^.nast;
end;
dl2:=0; pom2:=l2;
while pom2 <> nil do begin //liczymy długość l2
dl2:=dl2+1;
pom2:=pom2^.nast;
end;
for i:=1 to dl1-dl2 do l1:=l1^.nast; //wyrównujemy odległość od końców list
for i:=1 to dl2-dl1 do l2:=l2^.nast;
while l1 <> l2 do begin //szukamy elementu wspólnego
l1:=l1^.nast;
l2:=l2^.nast;
end;
PierwszyWspólny:=l1;
end;
Koszt czasowy: liniowy względem sumy długości list
Koszt pamięciowy: stały
Ćwiczenie
Skąd wiadomo, że w ostatnim while'u l1 i l2 sa zawsze różne od nil ?
Zadanie 8 (Listy z cyklem)
Napisz funkcję która sprawdzi czy dana l typu lista jest listą prostą czy też listą z cyklem.
Wskazówka 1
{{{3}}}
Rozwiązanie 1
{{{3}}}
Zadanie 9 (Długość cyklu w liście z cyklem)
Napisz funkcję która dla danej listy z cyklem obliczy długość cyklu.
Wskazówka 1
{{{3}}}
Rozwiązanie 1
{{{3}}}
Wskazówka 2
{{{3}}}
Rozwiązanie 2
{{{3}}}