//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*> bool es_menor(btree<int> &T1,btree<int>::iterator n1, btree<int> &T2,btree<int>::iterator n2) { // Si los dos estan vacios, entonces no cae en // ninguno de los casos especificados y debe // retornar false. if (n1==T1.end() && n2==T2.end()) return false; // Si `n1==end()' y `n2!=end()' entonces // `*n1<*n2' y debe retornar `true'. if (n1==T1.end()) return true; // Si `n1!=end()' y `n2==end()' entonces // `*n1>*n2' y no entra en ninguno de los casos, // por lo tanto debe retornar `false'. if (n2==T2.end()) return false; // Las dos raices son dereferenciables. // Si son distintas ya puede retornar un valor. if (*n1 < *n2) return true; if (*n1 > *n2) return false; // Si llega aqui, las dos raices son dereferenciables // e iguales. Hay que comparar los arboles de los hijos. // Si `Ai' y `Bi' son diferentes retornar un valor... if (es_menor(T1,n1.left(),T2,n2.left())) return true; if (es_menor(T2,n2.left(),T1,n1.left())) return false; // ... finalmente retorna el valor de comparacion // de los hijos derechos. return es_menor(T1,n1.right(),T2,n2.right()); }
void find_in_tree(const btree<T> &b, T val) { typename btree<T>::const_iterator iter = std::find(b.begin(), b.end(), val); if (iter == b.end()) std::cout << val << " not found" << std::endl; else std::cout << val << " found" << std::endl; }
bool equalp(btree<int> &A, btree<int>::iterator a, btree<int> &B, btree<int>::iterator b, bool (*eq)(int x,int y)) { if ((a == A.end()) != (b == B.end())) return false; if (a == A.end()) return true; if (!eq(*a,*b)) return false; return equalp(A,a.left(),B,b.left(),eq) && equalp(A,a.right(),B,b.right(),eq); }
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*> void packleft(btree<int> &T,btree<int>::iterator n) { // Si el arbol esta vacio no hay que hacer nada if (n==T.end()) return; // `l,r' son los hijos btree<int>::iterator l = n.left(), r = n.right(); // Solo en el caso de que `l' es vacio y `r' // no, entonces hay que hacer un splice. // Notar que hay que refrescar `l,r' if (l==T.end() && r!=T.end()) l = T.splice(l,r); r = n.right(); // Aplica recursivamente a `l' y `r' packleft(T,l); packleft(T,r); }
// ------------------------------------------------------------------- int cont_nod_prof(btree<int> &A,btree<int>::iterator n, int prof) { if (n==A.end()) return 0; else return (prof<=0) + cont_nod_prof (A,n.left(),prof-1) + cont_nod_prof (A,n.right(),prof-1); }
T reduce (btree <T> & Q, T (*f_asociat) (T,T), T v_ini) { T z ; if (Q.begin() != Q.end()) z = reduce (Q, Q.begin (), f_asociat, v_ini, f_iden<T>); else z = v_ini; return z ; }
// ------------------------------------------------------------------- // Introducimos una mejora inspirada en la programacion funcional. // Pasamos un argumento que es una funcion que toma dos argumentos // de entrada x,y y retorna bool. // La funcion retorna un bool que indica si el elemento // correspondiente debe estar en C, y si es asi retorna // por referencia en el argumento z el valor del elemento // a insertar. void tree_intersection (btree<int> &A, btree<int>::iterator nA, btree<int> &B, btree<int>::iterator nB, btree<int> &C, btree<int>::iterator nC, bool (*fun) (int x, int y, int &z)) { // Si habia algo en C limpiarlo nC = C.erase(nC); int w; // Solo hace algo si los dos nodos no son Lambda y si // `fun' retorna verdadero. if (nA != A.end() && nB != B.end() && fun(*nA,*nB,w)) { // insertar nC = C.insert(nC,w); // Llama recursivamente tree_intersection (A,nA.left(),B,nB.left(), C,nC.left(),fun); tree_intersection (A,nA.right(),B,nB.right(), C,nC.right(),fun); } // end if }
U reduce (btree <T> & Q, U (*f_asociat) (U,U), U v_ini, U (*f_predica) (T) ) { U z ; if (Q.begin() != Q.end ()) z = reduce (Q, Q.begin(), f_asociat, v_ini, f_predica); else z = v_ini ; return z ; }
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*> // Cuando se define una relacion de orden vimos que basta // con definir <, >, <= o >=. Una alternativa es una // funcion `comp(a,b)' que retorna -1 si T1<T2, 0 si T1==T2, // +1 si T1>T2. (En Perl es el operador `<=>'). // Esta funcion seria el operador `comp' para // arboles binarios. Ademas, esta implementacion // permite pasar una funcion de comparacion // (programacion funcional) int comp_btree(btree<int> &T1,btree<int>::iterator n1, btree<int> &T2,btree<int>::iterator n2, int (*comp)(int x,int y)) { // Si son Lambda => son iguales. if (n1==T1.end() && n2==T2.end()) return 0; // Si `n1==end()' y `n2!=end()' // entonces `*n1<*n2'. // debe retornar -1. if (n1==T1.end()) return -1; // Si `n1!=end()' y `n2==end()' // entonces `*n1>*n2'. if (n2==T2.end()) return +1; // Si `comp(*n1,*n2)!=0' entonces debe // retornar el valor de `comp' int v = comp(*n1,*n2); if (v) return v; // Si `comp_btree(Ai,Bi) != 0' entonces debe // retornar el valor. v = comp_btree(T1,n1.left(),T2,n2.left(),comp); if (v) return v; // Retorna el valor `comp_btree(Ai,Bi) != 0' return comp_btree(T1,n1.right(),T2,n2.right(),comp); }
U reduce (btree<T> & Q, typename btree<T>::iterator n, U (*f_asociat) (U,U), U v_ini, U (*f_predica) (T) ) { typename btree<T>::iterator c1, c2 ; U valor ; U h1, h2 ; if ( n == Q.end() ) return v_ini ; c1 = n.left (); c2 = n.right (); h1 = reduce (Q, c1, f_asociat, v_ini, f_predica); h2 = reduce (Q, c2, f_asociat, v_ini, f_predica); valor = v_ini + (h1 + h2) ; valor = f_asociat (h1,valor); valor = f_asociat (h2,valor); return f_asociat (f_predica (*n), valor); }
// ------------------------------------------------------------------- // Esta es otra variante. La funcion `fun' ahora es llamada sobre // todos los pares correspondientes `x' en `A' e `y' en 'B'. En los // casos en que alguno de los dos es Lambda, entonces el valor pasado // correspondiente es `undef'. void tree_union (btree<int> &A, btree<int>::iterator nA, btree<int> &B, btree<int>::iterator nB, btree<int> &C, btree<int>::iterator nC, bool (*fun)(int x,int y,int &z), int undef=0) { nC = C.erase(nC); int w; if (nA == A.end() && nB == B.end()) return; else if (nA != A.end() && nB != B.end() && fun (*nA,*nB,w)) { nC = C.insert (nC,w); tree_union (A, nA.left(), B, nB.left(), C, nC.left(), fun); tree_union (A, nA.right(),B,nB.right(), C, nC.right(),fun); } else if (nA == A.end() && fun (undef,*nB,w)) { nC = C.insert(nC,w); tree_union (A, A.end(), B, nB.left() , C, nC.left(), fun); tree_union (A, A.end(), B, nB.right(), C, nC.right(),fun); } else if (nB == B.end() && fun (*nA,undef,w)) { nC = C.insert (nC,w); tree_union (A, nA.left(), B, B.end(), C, nC.left(), fun); tree_union (A, nA.right(), B, B.end(), C, nC.right(), fun); } // end if }
///void foo(const btree<int> &b) { void foo(btree<int> &b) { std::copy(b.begin(), b.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; }