task1_bb.cpp

// $Id$
/* COMIENZO DE DESCRIPCION

Diversas operaciones en un Arbol Binario (AB)
[se asume que sus etiquetas son n\'umeros enteros positivos]:
altura          : calcula la altura;
cta\_hojas      : cuenta el n\'umero de hojas;
max\_etiq\_arbol: obtiene la m\'axima etiqueta de todo el \'arbol;
max\_epar\_arbol: obtiene la m\'axima etiqueta par del \'arbol;
max\_etiq\_hojas: obtiene la m\'axima etiqueta de solo las hojas;
sum\_etiq\_arbol: obtiene la suma de todas las etiquetas;
f\_aplica: ejemplo simple de {\bf programaci\'on funcional}
usando, una vez por vez, las funciones f\_duplica y f\_mitad
(ver en task1\_bo.cpp las equivalentes para \'arbol orientado). 
keywords: arbol binario

  FIN DE DESCRIPCION */
// -------------------------------------------------------------------
// Recordar que (errores tipicos en examen !!):
// 1) las funciones declaradas como "int" deben devolver en cualqueer 
//    caso un valor "int" y, por lo tanto, todo "return" debe devolver 
//    un "entero"; 
// 2) un razonamiento equivalente cuando en otros ejercicios
//    haya que devolver un "bool" o un "float";
// 3) solamente las funciones "void" NO devuelven explictamente
//    un valor y es la unica vez que el "return" no tendra argumentos 
//
// -------------------------------------------------------------------
#include <iostream>
#include "./btree.h"
#include "./util.h"
#include "./util_btree.h"
using namespace aed;
using namespace std;

// -------------------------------------------------------------------
int altura (btree<int> & T, btree<int>:: iterator n) {
  int h1, h2, hmax ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if (n == T.end ()) return -1 ;
  // altura del sub-arbol izquierdo "h1" y derecho "h2" por recursion
  h1 = altura (T, n.left  () ) ;
  h2 = altura (T, n.right () ) ;
  // selecciona la mayor altura de los subarboles izquierdo y derecho
  if (h1 > h2) {
    hmax = h1 ; }
  else {
    hmax = h2 ; 
  } // end if
  // devuelve la mayor altura
  return (1 + hmax) ;
} // end int

// -------------------------------------------------------------------
int cta_hojas (btree<int> & T, btree<int>:: iterator n) {
  int  p1, p2, p ;
  bool b1, b2 ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if ( n == T.end () ) return 0 ;
  // si el nodo "n" es hoja entonces devuelve 1
  b1 = ( n.left  () == T.end () ) ;
  b2 = ( n.right () == T.end () ) ;
  if ( b1 && b2 ) return 1 ;
  // cta hojas sub-arbol izquierdo "p1" y derecho "p2" por recursion
  p1 = cta_hojas ( T, n.left  () );
  p2 = cta_hojas ( T, n.right () );
  // devuelve la suma de las hojas de los sub-arboles izq. y der.
  p  = p1 + p2 ;
  return p ;
} // end int

// -------------------------------------------------------------------
int max_etiq_arbol (btree<int> & T, btree<int>:: iterator n) {
  int x1, x2, xmax ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if (n == T.end ()) return -1;
  // max etiq. de los subarb. izq. "x1" y der. "x2" por recursion
  x1 = max_etiq_arbol (T, n.left  () ) ;
  x2 = max_etiq_arbol (T, n.right () ) ;
  // selecciona y devuelve "xmax" como el mayor de (*n, x1, x2)
  xmax = *n ;
  if (x1 > xmax) xmax = x1 ;
  if (x2 > xmax) xmax = x2 ;
  return xmax ;
} // end int

// -------------------------------------------------------------------
int max_etiq_hojas (btree<int> & T, btree<int>:: iterator n) {
  int  x, x1, x2, xmax ;
  bool b1, b2 ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if (n == T.end ()) return -1 ;
  // si el nodo "n" es hoja entonces devuelve su etiqueta
  x = *n ;
  b1 = ( n.left  () == T.end () ) ;
  b2 = ( n.right () == T.end () ) ;
  if (b1 && b2) return x ;
  // max etiq_hojas de los subarb. izq. "x1" y der. "x2" por recursion
  x1 = max_etiq_hojas (T, n.left  ());
  x2 = max_etiq_hojas (T, n.right ());
  // selecciona y devuelve "xmax" como el mayor de (*n, x1, x2)
  xmax = 0 ;
  if  (x1 > xmax) xmax = x1 ;
  if  (x2 > xmax) xmax = x2 ;
  return xmax;
} // end int

// -------------------------------------------------------------------
int max_epar_arbol (btree<int> & T, btree<int>:: iterator n) {
  int x1, x2, xmax ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if (n == T.end ()) return -1;
  // max etiq. par de los subarb. izq. "x1" y der. "x2" por recursion  
  x1 = max_epar_arbol (T, n.left  () ) ;
  x2 = max_epar_arbol (T, n.right () ) ;
  // selecciona y devuelve "xmax" como el mayor par de (*n, x1, x2)
  if (*n % 2 == 0) xmax = *n ; else xmax = 0 ;
  if (x1 > xmax && x1 % 2 == 0)  xmax = x1 ;
  if (x2 > xmax && x2 % 2 == 0)  xmax = x2 ;
  return xmax ;
} // end int

// -------------------------------------------------------------------
int  sum_etiq_arbol (btree<int> &T, btree<int>::iterator n) {
  int  s1, s2, suma ;
  // la recursion finaliza cuando ingresa los hijos de las hojas
  if (n == T.end ()) return 0 ;
  // suma recursiva de las etiq. de los subarb. izq. "s1" y der. "s2"
  s1 = sum_etiq_arbol (T, n.left  ());
  s2 = sum_etiq_arbol (T, n.right ());
  // devuelve "suma" como la suma de (*n, s1, s2)
  suma = *n + s1 + s2;
  return (suma) ;
} // end int

// -------------------------------------------------------------------
//
// Un par de ejemplos *SIMPLES* de Programacion Funcional:
//
// 1) Primero definimos una funcion "aplica" que hace el trabajo 
//    RECURSIVO. La tarea que haga dependera de la "f_usuario" que 
//    se defina cuando se llame al "wrapper" desde, por ejemplo, el 
//    programa principal;
//
// 2) Por didactica, la "f_usuario" la restringiremos: 
//    2.1) a ser de tipo entero;
//    2.2) con un unico argumento de tipo entero.
//
// 3) Luego, podremos implementar cualquier "f_usuario" que 
//    satisfaga tales restricciones. Como un par de ejemplos muy 
//    simples incluimos "f_duplica" y "f_mitad".
// -----------------------------------------------------------------
void aplica (btree<int>           &T,
             btree<int>::iterator  n,
             int (*f_usuario) (int) ) {
 if (n == T.end () ) return;
 *n = f_usuario (*n);
 aplica (T, n.left (), f_usuario);
 aplica (T, n.right(), f_usuario);
}
void aplica (btree<int> &T, int (*f_usuario) (int) ) {
  aplica (T, T.begin (), f_usuario) ;
}
int f_duplica (int i) {
 return (2*i) ;
}
int f_mitad (int i) {
 return (i/2) ;
}

// -------------------------------------------------------------------
void tareas (btree<int> & Q) {
  btree <int> U;
  int n1, n2, n3, n4, n5, n6 ;

  cout << endl ;
  cout << "Arbol binario: " ; Q.lisp_print () ; 
  cout << endl ;

  n1 = altura         ( Q, Q.begin () ) ;
  n2 = cta_hojas      ( Q, Q.begin () ) ;
  n3 = max_etiq_arbol ( Q, Q.begin () ) ;
  n4 = max_epar_arbol ( Q, Q.begin () ) ;
  n5 = max_etiq_hojas ( Q, Q.begin () ) ;
  n6 = sum_etiq_arbol ( Q, Q.begin () ) ;

  cout << "altura del arbol                  = " << n1 << endl;
  cout << "nro de hojas en el arbol          = " << n2 << endl;
  cout << "max etiqueta de todo el arbol     = " << n3 << endl;
  cout << "max etiqueta par de todo el arbol = " << n4 << endl;
  cout << "max etiqueta de las hojas         = " << n5 << endl;
  cout << "suma de todas las etiquetas       = " << n6 << endl;

  cout << endl ;
  cout << "ejemplos *SIMPLES* de programacion funcional: " << endl ;

  cout << endl ;
  cout << "1) devuelve el doble de las etiquetas de un AB " << endl ;
  U = Q ;
  cout << "   AB antes  : " ; U.lisp_print () ; cout << endl ;
  aplica (U, f_duplica) ;
  cout << "   AB despues: " ; U.lisp_print () ; cout << endl ;

  cout << endl ;
  cout << "2) devuelve la mitad de las etiquetas de un AB " << endl ;
  U = Q ;
  cout << "   AB antes  : " ; U.lisp_print () ; cout << endl ;
  aplica (U, f_mitad) ;
  cout << "   AB despues: " ; U.lisp_print () ; cout << endl ;
}

// -------------------------------------------------------------------
int main () {
  int kaso = 1 ;

  cout << endl; 
  cout << "tareas varias en un arbol ordenado binario" << endl ;

  if      (kaso == 1) {
    typedef int dato;
    const dato BP=-1, EP=-2, NE=-3, EL=-4;
    btree <dato> Q;
    //tareas (Q); 
    list <dato> L;
    dato l[]={BP,1,2,BP,8,BP,4,NE,BP,5,3,NE,EP,EP,BP,9,NE,6,EP,EP,EP,EL};
    insertl (L, l, EL);
    list2btree (Q, L, BP, EP, NE);
    tareas (Q); 
  }
  else if (kaso == 2) {
    btree <int> T;
    for (int j = 0 ; j < 1 ; j++) {
      T.clear ();
      make_random_btree (T, 10, 1.2); // 1.1
      tareas (T) ;
    } // end j
  } // end if

  cout << endl ;
  return 0 ;
} // end main
// -------------------------------------------------------------------

Generated by GNU Enscript 1.6.6.