Try   HackMD

ADS úlohy D - Rovnováha

Předpokládám, že o stromu nevím nic, měl bych jej tak nejprve redukovat a nikoli přestavovat za běhu. Tedy:

  1. Strom přeměním na spojový seznam
  2. Ze spojového seznamu udělám vyvážený vyhledávací strom.

Jak na to, mám-li omezenou paměť? Pravděpodobně budu muset při každém kroku prvky umazávat.

1.

Plánuju-li udělat spojový seznam, pak by umazání šlo provést v konstantním (a celkově lineárním) čase; jdu-li doleva (hledám nejmenší vrchol), ten bude určitě list. Druhý nejmenší vrchol bude jeho otec, a zde již mohou nastávat problémy. Předpokládám-li však, že se nějak chytře dokážu dostat "nahoru", mohu se pouze vrátit do otce a přepojit jej.

Tím pádem vždy pouze umazávám vrchol s

1 synem nebo žádným.

Předtím, než daný prvek smažu, jej samozřejmě zapíšu do spojového seznamu.

2.

Jakmile mám daný spojový seznam, musím z něj udělat vyvážený vyhledávací strom. To lze snadno v případě, je-li počet prvků roven

2k1 (takže třeba
7
prvků), v takovém případě bude prostřední kořenem a zbydou mi dva podstromy, které musím zkontstruovat.

Má-li levý podstrom

n2 prvků, pak pravý podstrom bude začínat na
n1n2
-tém prvku spojového seznamu.

Vzhledem k této skutečnosti (pamatuji si, kde začnu dělat nový strom) také nemusím prvky uchovávat, při konstrukci stromu je mohu rovnou mazat.

Tedy např. pro 8 prvků:

  1. Udělám strom z 1-4,6-8 a kořenem bude 5
  2. Udělám strom z 1-2,4 a kořenem bude 3
  3. Udělám strom z 1, kořenem bude 2
  4. Kořenem je 2, nemám pravý podstrom, vracím se zpět
  5. Kořenem je 3, napojím pravý podstrom
  6. Kořenem pravého postromu je 4, vracím se zpět

Při každém takovém volání musím vrátit kořen.

Bohužel, nevím, zdali je akové rekurzivní volání povoleno (pokud s tím přehazuji i prvky), zřejmě by se to nevlezlo do paměti.