Sortowanie Dane wejściowe: ciąg n-liczb (kluczy) (a1,a2,a3,...,an−1

Transkrypt

Sortowanie Dane wejściowe: ciąg n-liczb (kluczy) (a1,a2,a3,...,an−1
Sortowanie
Dane wejściowe: ciąg n-liczb (kluczy) (a1 , a2 , a3 , . . . , an−1 , an )
Dane wyjściowe: permutacja ciągu wejściowego (a01 , a02 , a03 , . . . , a0n−1 , a0n ) taka, że a01 ¬ a02 ¬ a03 ¬ . . . ¬ a0n−1 ¬ a0n .
Będziemy zakładać, że ciąg ten stanowią elementy tablicy A[1...n].
Zadanie 1
Przygotuj algorytm programu - sortowanie przez wstawianie.
a) Przeanalizuj algorytm programu - sortowanie przez wstawianie.
Schemat blokowy tego algorytmu:
Dane wejściowe: tablica A[1...n], którą należy przesortować, Len([A]) oznacza liczbę elementów tablicy.
begin
i := 2;
while i < Len([A]) + 1 do
begin
key := A[i]; j := i − 1;
while j > 0 and key < A[j] do
begin
A[j + 1] := A[j];
j := j − 1;
end
A[j + 1] := key;
i := i + 1;
end
end
Dane wyjściowe: przesortowana tablica A[n].
b) Niech A oznacza napis SORTOWANIE, Len[A] = 10.
Podaj stan tablicy [A] po kolejnych wyjściach z pętli głównej.
1
i key
2 O
3
R
4
5
T
O
6
7
8
9
10
W
A
N
I
E
j A[j] A
1
S
SSRTOWANIE
OSRTOWANIE
2
S
ORRTOWANIE
1 O
ORSTOWANIE
3
S
ORSTOWANIE
4
T
ORSTTWANIE
3
S
ORSSTWANIE
2
R
ORRSTWANIE
1 O
OORSTWANIE
5
T
OORSTWANIE
AOORSTWNIE
ANOORSTWIE
AINOORSTWE
AINOORSTWE
c) Jaka jest złożoność tego algorytmu?
Jak często ze sprawdzenia warunku j > 0 wyniknie, że j = 0 ??
Co najwyżej raz. w C# można zmienić kolejność sprawdzania
while key < A[j] and j > 0 do
Ile razy wykonywana jest operacja porównania?
Jaka jest minimalna, a jaka maksymalna liczba przesunięć
A[j + 1] ← A[j]?
Czy algorytm jest stabilny?
Rozwiązanie
Złożoność obliczeniowa
Pamięciowa – algorytm sortuje w miejscu.
Czasowa:
Liczba porównań – koszt pesymistyczny W (n) = n(n−1)
2
Liczba porównań – koszt oczekiwany A(n) = n(n+1)
4
Liczba półzamian = Liczba porównań.
Zalety
Algorytm sortowanie przez wstawianie jest stabilny.
d) Zaimplementuj ten algorytm w języku C# dla listy liczbowej.
2
e) Zaimplementuj w C# algorytm sortowania przez wstawianie ze strażnikiem:
begin
min := 1;
for i := 2 to Len([A]) do
if A[i] < A[min] then min := i;
zamień(A[1], A[min]);
for i := 2 to Len([A]) do
begin
key := A[i];
j := i − 1;
while key < A[j] do
{A[1] − −strażnik}
begin
A[j + 1] := A[j];
j := j − 1;
end
A[j + 1] := key;
end
end
3
Zadanie 2
Sortowanie przez wstawianie – z wyszukiwaniem binarnym.–wazniak.mimuw.edu.pl
W algorytmie sortowania przez wstawianie, jeden z kroków polega na wstawieniu elementu A[i] do uporządkowanego podciągu A[1, . . . , i − 1].
Należy wyszukać największy taki indeks j ¬ i, taki że A[j − 1] ¬ x = A[i].
Miejsce, w które należy wstawić element A[i], można znaleźć za pomocą wyszukiwania binarnego.
Przygotuj algorytm takiego programu i przeanalizuj go na przykładzie listy
[1, 6, 5, 7, 9, 6].
Rozwiązanie.
Możliwe są dwa przypadki:
1. ∀j<i A[j] ¬ x = A[i], czyli klucz x jest na właściwym miejscu
2. x < A[i − 1]. W takim przypadku należy wyszukać binarnie największy
taki indeks j < i, taki że A[j − 1] ¬ x = A[i].
W przypadku konieczności zastosowania wyszukiwania binarnego x w liście
A[0 : i] możliwe są przypadki:
1. x nie występuje na tej liście, należy znaleźć j < i, A[j − 1] < x < A[j]
2. x występuje co najmniej raz na tej liście, należy znaleźć
j < i, A[j − 1] = x ∧ A[j] > x.
Oznacza to, że powinien być zwracany prawy skrajny element lewej podlisty,
a warunek porównania powinien być postaci if x <= A[k] then return k.
l := 0; p := len(A) − 1;
while (l < p) do
begin
k := (l + p) div 2;
if x > A[k] then
l := k + 1;
else
p := k;
end;
if x = A[p] then p = p + 1
return p;
W tym algorytmie liczbę wykonywanych porównań można wyznaczyć następująco: w iteracji o numerze i zewnętrznej pętli for wykonuje się co najwyżej
dlog ie porównań pomiędzy elementami sortowanego ciągu czyli złożoność obliczeniowa jest równa
n
X
dlog ie = ndlog ne − 2dlog ne + 1. W algorytmie tym,
i=2
4
liczba porównań została zmniejszona do liniowo-logarytmicznej, ale liczba
przestawień elementów w tablicy, koniecznych do zrobienia tych miejsc, w
dalszym ciągu jest w pesymistycznym przypadku kwadratowa.
Ta obserwacja pokazuje, że do analizy złożoności algorytmu, dobór operacji
dominujących jest kluczowy dla jakości tej analizy.
Zadanie 3 X
n
Pokaż, że
dlg ie = ndlg ne − 2dlg ne + 1.
i=2
Rozwiązanie.
Rozważmy sumę
n
X
dlg ie.
i=2
Niech p = blg nc, p + 1 = dlg ne, czyli 2p < n ¬ 2p=1 .
Widać, że
k+1
2X
dlg ie = 2k dlog(2k + i)e = 2k (k + 1).
i=2k +1
czyli
n
X
dlg ie =
i=2
k+1
p−1
X 2X
dlg ie + (n − 2 )dlg ne =
k=0 i=2k +1
p−1
X
Ile wynosi suma
p
p−1
X
2k (k + 1) + (n − 2p )dlg ne.
k=0
2k (k + 1) ?
k=0
Sprawdźmy to dla p = 4 :
1 · 20 +
2 · 21 +
20 +
21 +
21 +
(24 − 1) +
3 · 24 +
3 · 24 +
3 · 24 +
Twierdzenie
p−1
X
3 · 22
22
22
22
+ 4 · 23
+
23
+
23
+
23
23
3
2
2
2 · (2 − 1) + 2 · (2 − 1) +
23
23 − (1 + 2 + 22 )
23 −
(23 − 1)
1
=
=
=
=
=
=
=
=
2k (k + 1) = (p − 1)2p + 1.
k=0
Dowód przez indukcję.
n
X
dlg ie = (blg nc − 1)2blg nc + 1 + (n − 2blg nc )dlg ne) = (dlg ne − 2)2blg nc +
i=2
1 + (n − 2blg nc )dlg ne) = ndlg ne − 2dlg ne + 1.
5

Podobne dokumenty