mkmirror.cpp

/* COMIENZO DE DESCRIPCION

   __USE_WIKI__
  Escribir una funcion #void make_mirror(tree<int> &T);# que
  convierte in-place al arbol #T# en su espejo. 
   [Tomado en segundo parcial 2011-10-27].
   keywords: arbol orientado

  FIN DE DESCRIPCION */
// -------------------------------------------------------------------

// Por ejemplo
//   si !+T=(1 (5 3 2 1) (10 9 7))+ entonces despues de hacer
//   !+make_mirror(T)+ debe quedar !+T=(1 (10 7 9) (5 1 2 3))+. 
//   \textbf{Ayuda:} Debe ir invirtiendo la lista de hijos para
//   cada nodo !+n+ y aplicar la funcion recursivamente sobre los
//   hijos. Para invertir los hijos se puede usar alguna de las
//   siguientes opciones:
//   % FIXME:= poner ejemplo
//   \begin{itemize}
//     \compactlist 
//   \item Usar un arbol auxiliar !+Taux+, insertar un elemento
//     cualquiera (p.ej. 0) en la raiz y hacer \emph{splice} para ir
//     moviendo cada uno de de los hijos de !+n+ a !+Taux+. Luego volver
//     a mover (con \emph{splice}) todos los hijos de !+Taux+ en !+n+,
//     pero de forma que queden invertidos.
//   \item Usar una lista de arboles !+list<tree<int>> L+. Mover los
//     hijos de !+n+ sucesivamente en nuevos arboles en la lista. Para
//     insertar un nuevo arbol en la lista simplemente hacemos
//     !+L.push_back(tree<int>())+. 
//   \item No usar ningun contenedor auxiliar, ir recorriendo los hijos
//     de !+n+ y moverlos en !+n.lchild()+. En este caso tener cuidado
//     con los iteradores.
//   \end{itemize}
//   %
//   \textbf{Curiosidad:} Notar que
//   !+ordprev(make_mirror(T))=reverse(ordpost(T))+ y 
//   !+ordpost(make_mirror(T))=reverse(ordprev(T))+.
//    keywords: arbol orientado

#include <cstdarg>
#include <cstdio>

#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include "./util.h"
#include "./tree.h"
#include "./util_tree.h"

using namespace aed;
using namespace std;

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
typedef tree<int>::iterator node_t;
void make_mirror(tree<int> &T,node_t n) {
  node_t c = n.lchild();
  if (c==T.end()) return;
  // Crea un arbol temporario `aux'. Mueve todos los hijos
  // de `n' com hijos de la raiz de `aux'. Como `aux'
  // inicialmente est'a vacio inserta algo en la raiz de
  // `aux'. Para eso inserta un nodo con cualquier etiqueta
  // (en este caso 0). En este proceso los hijos de `n' quedan
  // en orden invertido en `aux'
  tree<int> aux;
  node_t m = aux.insert(aux.begin(),0);
  node_t d = m.lchild();
  while (c!=T.end()) {
    d = aux.splice(d,c);
    c = n.lchild();
  }

  // Ahora trate todos los hijos de la raiz de `aux' a
  // `n' en el mismo orden (de manera que queden invertidos). 
  c = n.lchild();
  d = m.lchild();
  while (d!=aux.end()) {
    c = T.splice(c,d); c++;
    d = m.lchild();
  }

  // Aplica recursivamente `make_mirror()' a los hijos de `n'
  c = n.lchild();
  while (c!=T.end()) make_mirror(T,c++);
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Wrapper
void make_mirror(tree<int> &T) {
  make_mirror(T,T.begin());
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Esta implementacion es completamente similar pero
// en vez de usar un arbol auxiliar usa una lista de
// arboles. 
typedef tree<int>::iterator node_t;
void make_mirror2(tree<int> &T,node_t n) {
  
  node_t c = n.lchild();
  if (c==T.end()) return;

  typedef list< tree<int> > list_t;
  list_t L;
  while (c!=T.end()) {
    L.push_back(tree<int>());
    tree<int> &tmp = L.back();
    tmp.splice(tmp.begin(),c);
    c = n.lchild();
  }

  list_t::iterator q = L.begin();
  c = n.lchild();
  while (q!=L.end()) {
    c = T.splice(c,q->begin());
    q = L.erase(q);
  }

  c = n.lchild();
  while (c!=T.end()) make_mirror2(T,c++);
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Wrapper
void make_mirror2(tree<int> &T) {
  make_mirror2(T,T.begin());
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {

  for (int j=0; j<10; j++) {
    printf("---- TRY TREE #%d ---------\n" ,j);
    tree<int> T, T2;
    make_random_tree(T,10,2);
    T2 = T;
    print_tree(T);
    make_mirror(T);
    printf("Con make_mirror():\n");
    print_tree(T);
    
    make_mirror2(T2);
    printf("Con make_mirror2():\n");
    print_tree(T2);
  }
  return 0;
}

Generated by GNU Enscript 1.6.6.