Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
Ahoj potreboval bych od nekoho kdo se v nich dobre vyzna aby mi zkontroloval zda reseni techto problemu je spravne diky :)
1.Smazte vsechny uzly v binarnim stromne pod urovni “depth”
delBelow(TNODE * root, int depth){
if(!root)
return 0;
if(!root->m_L && !root->m_R)
return 0;
if(depth < 1){
free(root->m_L);
free(root->m_R);
root->m_L = NULL;
root->m_R = NULL;
}
if(root->m_L) delBelow(root->m_L, depth - 1);
if(root->m_R) delBelow(root->m_R, depth - 1);
}2.Realizujte funkci sumLeaves, která sečte hodnoty (uložené v proměnné m_Data) listů, které neukazují na žádný další list, (nejnižších úrovní každé cesty) v binárního stromu předaném ukazatelem na jeho kořen.
int sumLeaves(TNODE *root){
if(!root)
return 0;
if(root->m_L || root->m_R){
return sumLeaves(root->m_L) + sumLeaves(root->m_R)
}
Return root->m_Data;
}3.Realizujte funkci, která pro zadaný kořen stromu vypočte počet listových uzlů.
int countLeaves(TNODE *root) {
if(!root)
return 0;
if(!root->m_L && !root->m_R)
return 0;
if(!root->m_L){
return 1 + countLeaves(m_R);
}
if(!root->m_R){
return 1 + countLeaves(m_L);
}
return 2 + countLeaves(m_L)+ countLeaves(m_R);
}4.Realizujte funkci CntInner, která pro zadaný kořen stromu vypočte počet vnitrnich uzlů. - tzn krom listu
int CntInner(TNODE *root){
if(!root)
return 0;
if(!root->m_L && !root->m_R)
return 0;
return 1 + CntInter(root->m_R) + CntInter(root->m_L)
}5. Spocitat pocet uzlu pouze s jednim potomkem.
int CntOneChild(TNODE *root){
if(!root)
return 0;
if(!root->m_L && !root->m_R)
return 0;
if(root->m_L && !root->m_R)
return 1 + CntOneChild(root->m_L);
if(root->m_L && !root->m_R)
return 1 + CntOneChild(root->m_R);
return CntOneChild(root->m_R) + CntOneChild(root->m_L);
}Offline

U toho prvniho problemu by se mi zdalo korektnejsi ty dva posledni radky presounout pred to nulovani, takhle:
if(root->m_L) delBelow(root->m_L, depth - 1);
if(root->m_R) delBelow(root->m_R, depth - 1);
if(depth < 1){
free(root->m_L);
free(root->m_R);
root->m_L = NULL;
root->m_R = NULL;
}Tak jak to mas, tak ti tam budou zustavat alokovane ty dalsi vetve ve vetsi hloubce jestli se nepletu (Protoze tim ze vynulujes m_L a m_R, tak delBelow se uz nezavola pro ty dalsi).
Offline

Ten 3 - Je pravda, ze listovy uzel je uzel, ktery nema dalsi potomky? Jestli ano, tak bych rekl, ze pro pripad if(!root->m_L && !root->m_R) by se mela vratit hodnota 1 (a ne 0), a v tech dalsi pripadech nepricitat 1 a 2, protoze v tech pripadech ten koren samotny neni listovym uzlem.
Offline

U toho 5 - tam jsi nejspis zkopiroval tu podminku, ale uz ji neupravil, takze tam mas dve stejne:
if(root->m_L && !root->m_R)
return 1 + CntOneChild(root->m_L);
if(root->m_L && !root->m_R)
return 1 + CntOneChild(root->m_R);Spis by tam melo byt neco jako:
if(root->m_L && !root->m_R)
return 1 + CntOneChild(root->m_L);
if(!root->m_L && root->m_R)
return 1 + CntOneChild(root->m_R);Mozna jsou i chyby jinde, mozna se naopak pletu a chyby tam nemas, akorat jsem psal navrhy na mista, ktera by se dala zkontrolovat :-)
Offline
Mam jeste jeden orisek se kterym si nevim rady. Mam zadany nesetrideny binarni strom a mam najit nejmensi hodnotu listu a tu z dane funkce vratit.
Uloha se ma resit bez globalnich promenych. Na nic nemuzu prijit, jinak funkce ma mit hlavicku int minLeaf(BNODE *root)
Diky za kazde postrceni
Offline
Nebolo by jednoducho prejsť strom do hĺbky trebárs. Zamysli sa, že vtedy vieš kedy prídeš do listu. A jednoducho zo všetkých listov si vybrať ten, ktorý má najmenšiu hodnotu.
Prejsť do hĺbky sa dá jednoducho, rekurzívne (kód je z knihy Algoritmy a programovací techniky):
procedure Pruchod1(U: Uk);
{pruchod binarnim stromem do hloubky pomoci rekurze.
U je ukazatel na koren zkoumaneho stromu}
begin
if U <> nil then
begin
writeln(U^.Info); {nebo jina akce s uzlem U}
Pruchod1(U^.L);
Pruchod1(U^.P)
end
end; {procedure Pruchod1}Časová zložitosť je O(n), kde n je počet vrcholov.
Offline
ahoj, no do hloubky se dostanu a najdu dane listy, ale jak zjistim ktery z danych listu to je. Kazdy list prece muze byt v jine hloubce. A navic cele to musi byt ve funkci ktera ma parametr jenom (BNODE * root) ? Mozna ze se ptam hloupe ale nedochazi mi to..
Offline
Mam zadany nesetrideny binarni strom a mam najit nejmensi hodnotu listu a tu z dane funkce vratit.
Ja som pochopil, že ty máš nájsť list ktorý má najmenšiu hodnotu zo všetkých listov, je to tak?
Ak áno, tak potom to nemá nič spoločné s tým, že v akej hĺbke ten list je.
Offline
Však si proste dáš nejakú premennú, ktorej priradíš konštantu "nekonečno". A vždy keď narazíš na hodnotu, ktorá je menšia ako hodnota premennej, tak si zapamätáš novú najmenšiu hodnotu. A spravíš to len ak si v liste.
Offline
No ak je to binárny strom, tak keď sú pointery left a right NULL, tak je to list.
Offline
jj to vim s tim jak poznam list a tak i to porovnavani ale dejme tomu ze by dany algoritmus vypadal takhle:
int minLeaf(BNODE *root){
int min = 999;
if(!root){
return 0;} //kontrola jestli je koren
if(root->right || root->left){
return cntOneChild(root->left) + cntOneChild(root->right); //projizdeni dalsich uzlu
}
if(!root->right && !root->left){ //najdu list
if(root->key < min){//key je dana hodnota listu
min = root->key;
return min;
}
}
}Nevrati mi to nahodou hodnotu vsech listu, protoze tuto funkci volam vicekrat a kdyz je volana tak promena min bude vzdy znova 999 ?
Offline
Nemohol by byť tento pseudokód dobrý?
int find_min(BNODE *root) {
int min = INFTY; int x;
if (root is list) return root->value;
else {
if(x=find_min(root->left) < min) min = x;
if(x=find_min(root->right) < min) min = x;
}
return min;
}Offline
Tak sem lehce poladil tvoje reseni a ozkousel a funguje, diky za postrkovani :)
int find_min(BNODE * root) {
int min = sizeof(int); int x=0;
if (!root->right && !root->left) return root->key;
else {
if(root->left && root->right){
if(find_min(root->left) < min) min = find_min(root->left);
if(find_min(root->right) < min) min = find_min(root->right);
}
if(!root->left && root->right){
if(find_min(root->right) < min) min = find_min(root->right);
}
if(root->left && !root->right){
if(find_min(root->left) < min) min = find_min(root->left);
}
}
return min;
}Offline
Jasné je to dobre. Však to moje bol len narýchlo napísaný pseudokód. Lepšie je keď si sa k tomu dopracoval sám. Môžeš označiť za vyriešené teda. :)
Offline