==== Hledání prvku ve stromu ==== [[strom_2019_ut|zdrojový text]] Funkce **search** je vlastne cyklus jdouci od korene dolu k listum. \\ Pokud najde hledany klic, vrati ukazatel na cely uzel stromu. \\ Pokud nenajde, vraci **nullptr**. \\ Parametrem je ukazatel na koren stomu a hodnota hledaneho klice. Pokud zavolate search (root, 7), \\ zkopiruje se hodnota ukazatele z promenne **root** do parametru **p** \\ Parametr **p** mohu menit, aniz bych ovlivnil promennou **root**. Konjunkce **&&** : \\ Pokud je levy parametr **false**, pravy parametr se jiz nevycisluje a vysledek je **false**. \\ V nasem pripade: pokud je **p** nulovy, vysledek vyrazu ''p != nullptr && p->key != k'' je **false** a cyklus se zastavi. \\ Pokud **p** neni nulovy, muzeme otestovat hodnotu ''p->key'' a zastavit, pokud potkame hledany klic. Item * search (Item* p, int k) { while (p != nullptr && p->key != k) { if (k < p->key) p = p->left; else p = p->right; } return p; } ==== Rekurzivní hledání prvku ==== Rekuzivni varianta hledani prvku, funkce **find**. \\ Prvni paramater je ukazatel na koren podstromu, ve kterem hledame. \\ Pokud je podstrom prazdny vratime **nullptr**. \\ Ve zbyvajici casti funkce, je **p** nenulovy. \\ Pokud koren podstromu obsahuje hledany klic, vratime ukazatel na tento podstrom. \\ Pokud je kledany klic mensi nez hodnota v koreni, \\ pouzijeme rekurzivne funkci **find** na levy podstrom. \\ A co tato nova funkce vrati to bude i vysledkem nasi funkce. \\ ** return find (p->left, k); ** Poznamka: slozene zavorky **{ }** uvnitr funkce nejsou nezbytne.\\ Za **if** nebo **else** nasleduje prave jeden prikaz. Item * find (Item* p, int k) { if (p == nullptr) { return nullptr; } else if (p->key == k) { return p; } else if (k < p->key) { return find (p->left, k); } else { return find (p->right, k); } } Funkce **find** je jen slozitejsi variantou funkce **search**. \\ Pro hledani ji nejspise nebudeme pouzivat, ale poslouzi nam pri navrhu funkce pro vkladani. ==== Vkladani prvku do stromu ==== void insert (Item * & p, int k) Prvni parameter je ukazatel a je predavany odkazem ( znak **&** ).\\ Pri volani insert (root, 7); se do paratetru **p** ulozi **odkaz** na promenou **root**. \\ Prekladac odkaz implementuje pomoci "skryteho" ukazatele ( v nasem pripade ukazatele opet na ukazatel. ) \\ Pokud promennou **p** menime, zmenime i obsah promenne **root**. Napr. //p = new Item;// \\ Pokud promennou **p** pouzivame, pouziva se obsah promenne **root**. Napr. //p == nullptr;// \\ Pokud cteme polozku **p**, pristupujeme k polozce **root**. Napr. //p->key == k;// \\ Pokud je strom prazdny, vytvorime **novou polozku** a jeji adresa je ulozena na misto kde bylo **nullptr** predstavujici nulovy koren puvodniho stromu. if (p == nullptr) { p = new Item; p->key = k; p->left = nullptr; p->right = nullptr; } Pokud je klic ktery chceme vlozit v koreni prave zpracovaneho stromu. Nebudu delat nic. (Ale muzete ohlasit chybu.) else if (p->key == k) { } Pokud je klic ktery chceme vlozit mensi nez hodnota v koreni prave zpracovaneho stromu, \\ rekurzivne zavolam funkci **insert**. \\ Jako paramatetr predam koren leveho podstromu. \\ Odkaz na levy podstrom se ulozi do parametru **p** nove zavolane funkce **insert**. else if (k < p->key) { insert (p->left, k); } A podobne pro pravy podstrom. Zde je cela funkce. void insert (Item * & p, int k) { if (p == nullptr) { p = new Item; p->key = k; p->left = nullptr; p->right = nullptr; } else if (p->key == k) { } else if (k < p->key) { insert (p->left, k); } else { insert (p->right, k); } } ==== Varianty vkládání bez odkazu (reference), ale s ukazatelem na ukazatel. ==== Můžete porovnat s funkcemi **enter** a **ent**, které používají dvojitý ukazatel. \\ ( Jen pro ilustraci, nedoporucuji pouzivat. ) void enter (Item * * p, int k) { if (*p == nullptr) { *p = new Item; (*p)->key = k; (*p)->left = nullptr; (*p)->right = nullptr; } else if ((*p)->key == k) { } else if (k < (*p)->key) { enter (&((*p)->left), k); } else { enter(&((*p)->right), k); } } void ent (Item * * p, int k) { bool cont = true; while (cont) { if (*p == NULL) { *p = new Item; (*p)->key = k; (*p)->left = NULL; (*p)->right = NULL; cont = false; } else if ((*p)->key == k) cont = false; else if (k > (*p)->key) p = &((*p)->right); else p = &((*p)->left); } }