Zadanie 4 zaawansowane Heapsort
Rozważmy poniższy algorytm sortowania przez kopcowanie n-elementowej tablicy
A.
FixHeap(A; heapSize; i)
1 l <-2 * i
2 r<- 2 * i + 1
3 if l ≤ heapSize
4 then if l = heapSize
5 then largest<- l
6 else if A[l] > A[r]
7 then largest<- l
8 else largest<- r
9 if A[i] < A[largest]
10 then zamien A[i] z A[largest]
11 FixHeap(A; heapSize; largest)
ConstructHeap(A; r; n)
1 if r ≤
2 then ConstructHeap(A; 2 * r; n)
3 ConstructHeap(A; 2 * r + 1; n)
4 FixHeap(A; n; r)
HeapSort(A; n)
1 ConstructHeap(A; 1; n)
2 for heapSize n downto 2
3 do zamien A[1] z A[heapSize]
4 FixHeap(A; heapSize - 1; 1)
Określ złożoność obliczeniowa procedury HeapSort.
FixHeap
Czas działania procedury FixHeap na poddrzewie rozmiaru n zaczepionym w danym węźle i wynosi Θ(1) na poprawienie zależności między A[i], A[2*i] i A[2*i+1] plus czas potrzebny na rekurencyjne wywołanie FixHeap na poddrzewie zaczepionym w jednym z synów węzła i. Poddrzewa węzła mają każde rozmiar najwyżej 2n/3- najgorszy przypadek występuje, gdy ostatni rząd w drzewie wypełniony jest do połowy- czas działania FixHeap może zatem być opisany rekurencją
Z twierdzenia o rekurencji uniwersalnej mamy a=1,b=3/2, f(n)=Θ(1)
- co oznacza wystąpienie przypadku 2.
Stosując ten przypadek wyliczamy, że
ConstructHeap
Do obliczenia złożoności tej procedury wykorzystamy metodę iteracyjną. Ustalamy równanie rekurencyjne:
T(n)=2T(n/2)+lgn
=lgn+2T(n/2)
=lgn+2(lg(n/2)+2T)
=lgn+2lgn-2lg2+22T(n/22)
=lgn+2lgn-2lg2+22))
=lgn+2lgn-2lg2+22lgn-22(22)+23T(n/23)
…
=lgn+2lgn-2lg2+22lgn-22lg(22)+…+2klgn-2klg(2k)+2k+1T(n/2k+1)
=lgn(1+2+22+..+2k)-(2+2*22+3*23+…+k*2k)
Tutaj założymy, że n=2k więc k=lgn.
Weźmy s=20+21+22+…+2k==2k+1 -1
By uzyskać tą formułę, należy podjąć następujące kroki
s = 20+21+22+…+2k
2s = 21+22+…+2k+2k+1
s = -1+2k+1
Stąd
Podobnie, weźmy
T=1*21+2*22+3*23+…+k*2k
2T=1*22+2*23+…+(k-1)*2k+ k*2k+1
T= -21-22-23-…-2k+k2k+1
= k2k+1-(21+22+…+2k)
= k2k+1-(2k+1-2)
=(k-1)2k+1+2
Z tych założeń:
T(n)=lgn(2k+1-1)-((k-1) 2k+1+2)
=2nlgn-lgn-2nlgn+2n-2
=2n-lgn-2
=O(n)
Zatem złożoność procedury ConstructHeap wynosi O(n).
Złożoność procedury HeapSort wynosi O(nlgn), ponieważ wywołanie ConstructHeap zajmuje czas O(n), a każde z n-1 wywołań FixHeap zajmuje czas O(lgn).