Tema
/
Algoritmai ir duomenų struktūros GO
Pamoka 12 / 15 Subalansuoti medžiai (AVL) ~55 min
Teorija

Garantija, iki milijono

Pirmame žingsnyje užsirašei spėjimą: koks bus aukštis prie milijono įrašų, kai įvestis griežtai didėjanti?

$ go test -run AVLHeightGrowth -v

         n   height     log2 n    h/log2n    cmps/lookup   rot/insert
      1000       10       10.0       1.00          8.987        0.990
     10000       14       13.3       1.05         12.363        0.999
    100000       17       16.6       1.02         15.689        1.000
   1000000       20       19.9       1.00         18.951        1.000

20.

Milijonas įrašų, blogiausia įmanoma įterpimo tvarka, ir bet kurį pavadinimą randi per 19 palyginimų.

Stulpelis h/log2n

1.00   1.05   1.02   1.00

Ne „maždaug logaritmas". Aukštis yra log2(n), suapvalintas.

Palygink su vienuoliktos pamokos ta pačia lentele, kur BST buvo maitinamas maišyta — jam palankia — įvestimi:

h ÷ log2 n
BST, maišyta įvestis (11 pamoka) 1.97 – 2.47
AVL, surikiuota įvestis (12 pamoka) 1.00 – 1.05

AVL medis blogiausiu atveju yra maždaug dvigubai negilesnis už BST jam geriausiu realiu atveju.

Ir tai galioja bet kuriai tvarkai

Vienuoliktos pamokos namų darbe reikėjo sugalvoti trečią blogiausią tvarką — nei didėjančią, nei mažėjančią. Atsakymas buvo zigzagas: imk pakaitomis iš abiejų likusios aibės galų. Jis irgi duodavo aukštį n.

n = 20000, riba 20.3

ascending    aukštis 15    0.999 rotacijos įterpimui
descending   aukštis 15    0.999 rotacijos įterpimui
zigzag       aukštis 18    1.623 rotacijos įterpimui

Zigzagas — brangiausia iš trijų: 1.62 rotacijos vienam įterpimui vietoj 1.0, ir medis trimis lygiais aukštesnis. Ir vis tiek gerokai po riba.

Būtent to ir reiškia žodis „garantija". Ne „mūsų bandytoms įvestims pavyko", o „nėra tokios įvesties, kuriai nepavyktų" — nes riba plaukia iš invarianto, kurį kiekvienas mazgas patikrina pats.

Kas pasikeitė, palyginti su vienuolikta pamoka

Vienuoliktos pamokos aštuntas žingsnis reikalavo keturių dalykų. Sudėkim juos šalia to, kas gauta:

reikalavimas ar įvykdytas
medis persitvarko įterpimo metu taip — rebalance grįžtant atgal
persitvarkymas kainuoja O(log n), ne O(n) taip — patikrų tiek, koks kelio ilgis
BST invariantas išlieka taip — TestRotationsPreserveTheOrdering
aukštis O(log n) garantuotai taip — riba, patikrinta testu

Ir tai reiškia, kad vienuoliktos pamokos testas dabar turi kristi. Taip ir yra: TestSortedInsertDegeneratesIntoAList reikalauja Height() == n, o šis medis duoda 14. Sulaužyti tą testą ir buvo šios pamokos tikslas.