Вы находитесь на странице: 1из 27

Arboles N-Arios

/ **

* Representa un árbol de objetos de tipo genérico T. El árbol se representa como

* un elemento raíz único que apunta a una Lista <Nodo <T>> de elementos secundarios. No hay

* restricción en el número de hijos que puede tener un nodo en particular.

* Este árbol proporciona un método para serializar el árbol en una lista haciendo un

* recorrido transversal de pedido anticipado. Tiene varios métodos para permitir una fácil
actualización de los nodos

* en el árbol.

*/

árbol de clase pública < T > {

Nodo privado < T > rootElement ;

/ **

* Ctor predeterminado.

*/

public Tree () {

super ();

/ **

* Devuelve el nodo raíz del árbol.

* @ devuelve el elemento raíz.

*/

public Node < T > getRootElement () {

devolver esto . rootElement ;

}
/ **

* Establecer el elemento raíz para el árbol.

* @param rootElement el elemento raíz para establecer.

*/

public void setRootElement ( Nodo < T > rootElement ) {

esto . rootElement = rootElement ;

/ **

* Devuelve el árbol <T> como una lista de objetos de nodo <T>. Los elementos de la

* Lista se generan a partir de un recorrido previo del pedido del árbol.

* @return a List <Node <T>>.

*/

public List < Node < T >> toList () {

List < Node < T >> list = new ArrayList < Node < T >> ();

caminar ( rootElement , list );

lista de retorno ; }

/ **

* Devuelve una representación de cadena del árbol. Los elementos se generan

* a partir de un recorrido previo al pedido del Árbol.

* @ devuelve la representación de cadena del árbol.

*/

public String toString () {

return toList (). toString ();

/ **
* Camina el árbol en estilo de pedido anticipado. Este es un método recursivo y se

llama * desde el método toList () con el elemento raíz como primer

argumento *. Se agrega al segundo argumento, que se pasa por referencia * a medida que se
repite en el árbol.

* @param element el elemento inicial.

* @param enumera la salida de la caminata.

*/

private void walk ( Nodo < T > elemento , Lista < Nodo < T >> lista ) {

lista . agregar ( elemento );

para ( Nodo < T > datos : elemento . GetChildren ()) {

walk ( datos , lista );

/ **

* Representa un nodo de la clase Tree <T>. El Nodo <T> también es un contenedor, y

* puede considerarse como una instrumentación para determinar la ubicación del tipo T

* en el Árbol <T>.

*/

nodo de clase pública < T > {

datos públicos de T ; Lista pública < Nodo < T >> hijos ;

/ **

* Ctor predeterminado.

*/

public Node () {
super ();

/ **

* Conveniencia de crear un nodo <T> con una instancia de T.

* @param data una instancia de T.

*/

public Node ( T data ) {

this ();

setData ( datos );

/ **

* Devuelve los hijos del nodo <T>. El árbol <T> está representado por un solo

* Nodo raíz <T> cuyos hijos están representados por una Lista <Nodo <T>>. Cada uno de

* estos elementos de Nodo <T> en la Lista puede tener hijos. El

método

getChildren () * devolverá los hijos de un Nodo <T>. * @return the children of Node <T>

*/

public List < Node < T >> getChildren () {

if ( this . children == null ) {

return new ArrayList < Node <>> ();

devuelve esto . los niños ;

/ **

* Establece los elementos secundarios de un objeto Nodo <T>. Consulte los documentos de
getChildren () para
* más información.

* @param crea la Lista <Nodo <T>> para configurar.

*/

public void setChildren ( List < Node < T >> children ) {

this . niños = niños ;

/ **

* Devuelve el número de elementos secundarios inmediatos de este nodo <T>.

* @ devuelve el número de hijos inmediatos.

*/

public int getNumberOfChildren () {

if ( children == null ) {

return 0 ;

volver hijos . tamaño ();

/ **

* Agrega un hijo a la lista de hijos para este Nodo <T>. La adición de

* el primer hijo creará una nueva Lista <Nodo <T>>.

* @param child un objeto Nodo <T> para establecer.

*/

public void addChild ( Nodo < T > child ) {

if ( children == null ) {

children = new ArrayList < Node < T >> ();

niños . agregar ( niño );

}
/ **

* Inserta un Nodo <T> en la posición especificada en la lista secundaria. * Lanzará una


ArrayIndexOutOfBoundsException si el índice no existe.

* @param indexa la posición para insertar en.

* @param child el objeto Nodo <T> para insertar.

* @throws IndexOutOfBoundsException si se lanza.

*/

public void insertChildAt ( int index , Node < T > child ) arroja IndexOutOfBoundsException {

if ( index == getNumberOfChildren ()) {

// esto es realmente un

addChild adjunto( niño );

volver ;

} else {

hijos . obtener ( índice ); // solo para lanzar la excepción y parar aquí

niños . agregar ( índice , hijo );

/ **

* Elimine el elemento Nodo <T> en el índice índice de la Lista <Nodo <T>>.

* @param indexa el índice del elemento a eliminar.

* @throws IndexOutOfBoundsException si se lanza.

*/

public void removeChildAt ( int index ) arroja IndexOutOfBoundsException {

children . eliminar ( índice );

public T getData () {
devolver esto . datos ;

public void setData ( datos T ) { esto . datos = datos ; }

public String toString () {

StringBuilder sb = new StringBuilder ();

sb . agregar ( "{" ). agregar ( getData (). toString ()). agregar ( ", [" );

int i = 0 ;

para ( Nodo < T > e : getChildren ()) {

if ( i > 0 ) {

sb . adjuntar( "," );

sb . agregar ( e . getData (). toString ());

i ++;

sb . agregar ( "]" ). agregar ( "}" );

volver sb . toString ();

Ejemplo 2
/ **

* Un objeto DAO base que debe ser extendido por todos nuestros DAO individuales. Esta

clase * proporciona la funcionalidad básica para interactuar con Hibernate ORM.

* @author Sujit Pal (sujit.pal@comcast.net)

* @version $ Revision $

*/
public abstract class AbstractHibernateDao extiende HibernateDaoSupport {

public AbstractHibernateDao () {

super ();

pública Serializable guardar ( Objeto entidad ) {

volver getHibernateTemplate (). guardar ( entidad );

public void saveOrUpdate ( entidad de objeto ) { getHibernateTemplate (). saveOrUpdate


( entidad ); }

actualización pública vacía ( entidad del objeto ) { getHibernateTemplate (). actualización


( entidad ); }

public void remove ( entidad de objeto ) { getHibernateTemplate (). eliminar ( entidad ); }

public Object get ( Class clazz , Serializable id ) {

return getHibernateTemplate (). obtener ( clazz , id );

pública de objetos de carga ( Clase clazz , Serializable ID ) {

volver getHibernateTemplate (). carga ( clazz , id );


}

public List find ( final String hqlQuery , final String [] params , final Object [] paramValues ,
final Type [] paramTypes , final Integer start , final Integer count ) {

return ( List ) getHibernateTemplate (). execute ( new HibernateCallback () {

public Object doInHibernate (Session session ) lanza HibernateException , SQLException


{

Query query = session . createQuery ( hqlQuery );

int paramsLength = ( params == null ? 0 : params . length );

if ( params ! = null ) {

if ( paramValues == null || paramValues . length ! = params .length ) {

throw new IllegalArgumentException ( "ParamValues no especificado por completo


para todos los parámetros" );

if ( paramValues == null || paramTypes . length ! = params . length ) {

arrojar nueva IllegalArgumentException ( "ParamTypes no completamente


especificado para todos los params" );

para ( int i = 0 ; i < paramsLength ; i++) {

consulta . setParameter ( params [ i ], paramValues [ i ], paramTypes [ i ]);

if ( inicio == nulo ) {

consulta . setFirstResult ( 0 );

} else {

consulta . setFirstResult ( start . intValue ());

if ( cuenta == nulo ) {

consulta. setMaxResults ( 0 );

} else {
consulta . setMaxResults ( count . intValue ());

consulta de devolución . lista (); } }, verdadero ); } }

/ **

* Dao para la tarea POJO.

*/

public class TaskDao extiende AbstractHibernateDao {

Privado final estático Logger log = Logger . getLogger ( TaskDao . class );

pública TaskDao () {

super ();

/ **

* Eliminar un objeto Task de la base de datos.

* @param task la Tarea para eliminar.

*/

public void remove ( tarea de tarea ) {

super . eliminar ( tarea );

/ **

* Guarda una Tarea en la base de datos si es nueva, de lo contrario la actualiza.


* @param tarea la tarea para insertar o actualizar.

* @ devuelve la identificación de la tarea.

*/

public Long saveOrUpdate ( tarea de tarea ) {

if ( task . getId () == null ) {

return ( Long ) save ( task );

} else {

actualización ( tarea );

tarea de retorno . getId (); }

/ **

* Devuelve la tarea a la que apunta la identificación de la tarea. Devuelve un NULL si la

tarea * no se encuentra en la base de datos.

* @param taskId el id de la tarea para buscar.

* @ devuelve el objeto Task correspondiente a la identificación.

*/

public Task get ( Long taskId ) {

return ( Task ) super . get ( tarea . clase , taskId );

/ **

* Devuelve todos los elementos secundarios de la Tarea que tiene la identificación principal
especificada.

* @param parentId la identificación de la tarea principal.

* @ devuelve una lista de tareas que son elementos secundarios de la tarea especificada.

*/

@SuppressWarnings ( "sin marcar " )


Lista pública < Tarea > findByParentId ( Long parentId ) { return super . find ( "de la tarea donde
parentId =: parentId" , nueva cadena [] { "parentId" }, nuevo objeto [] {

parentId },

nuevo Tipo [] { Hibernate . LARGO },

nuevo entero ( 0 ), nuevo entero ( 1 ));

/ **

* Devuelve la primera tarea con el nombre especificado. Por lo general, esto nunca * se usará
directamente desde la aplicación, principalmente para su uso en pruebas.

* @param taskName el nombre de la tarea a devolver.

* @ devuelve la primera tarea con el nombre especificado.

*/

@SuppressWarnings ( "sin marcar " )

Tarea pública findByName ( String taskName ) { Lista < Tarea > tareas = super . find ( "from Task
donde taskName =: taskName" , nueva Cadena [] {

"taskName" },

nuevo Objeto [] { taskName },

nuevo Tipo [] { Hibernate . STRING },

nuevo entero ( 0 ), nuevo entero ( 1 ));

tareas de retorno . obtener ( 0 ); } }

/ **

* Objeto de acceso a datos para el objeto TaskTree. Este no es un verdadero Dao, ya que

* delega en el objeto TaskDao para cualquier operación de base de datos.


*/

public class TaskTreeDao {

Privado estático final Logger log = Logger . getLogger ( TaskTreeDao . class );

privada TaskDao taskDao ;

public TaskTreeDao () {

super ();

public void setTaskDao ( TaskDao taskDao ) {

esto . taskDao = taskDao ;

/ **

* Guarda un objeto TaskTree.

* @param taskTree un objeto TaskTree.

*/

public void saveOrUpdate ( TaskTree taskTree ) {

Lista < Nodo < Tarea >> tareas = taskTree . toList ();

// guarde el árbol en orden inverso, comenzando desde los nodos hoja

// y subiendo hasta la raíz del árbol.

int numberOfNodes = tareas . tamaño ();

para ( int i = numberOfNodes - 1; i > = 0 ; i -) {

Nodo < Tarea > taskElement = tareas . obtener ( i );

Tarea tarea = taskElement . getData ();

taskDao . saveOrUpdate ( tarea );

Long parentId = tarea . getId ();


for ( Iterator < Node < Task >> it = taskElement .getChildren (). iterador (); eso . hasNext
();) {

Nodo < Tarea > childElement = it . siguiente ();

Tarea childTask = childElement . getData ();

childTask . setParentId ( parentId );

taskDao . saveOrUpdate ( childTask );

/ **

* Obtiene un solo TaskTree por id. Esta es la cabeza de un método recursivo llamado

* a getRecursive ().

* @param id el id del TaskTree.

* @ devuelve un TaskTree para esa identificación.

*/

public TaskTree get ( Long ID ) {

TaskTree taskTree = new TaskTree ();

Nodo < Tarea > rootElement = nuevo Nodo < Tarea > ( taskDao . Get ( id ));

getRecursive ( rootElement, taskTree );

taskTree . setRootElement ( rootElement );

return taskTree ;

/ **

* Desciende recursivamente el árbol y llena el objeto TaskTree.

* @param taskElement el nodo raíz.

* @param tree el objeto TaskTree para rellenar.

*/
private void getRecursive ( Nodo < Task > taskElement , TaskTree tree ) {

List < Task > children = taskDao . findByParentId ( taskElement . getData (). getId ());

Lista < Nodo < Tarea >> childElements = new ArrayList < Nodo < Tarea >> ();

for ( Iterator < Task > it = children . iterator (); it . hasNext ();) {

Task childTask = it . siguiente ();

Nodo < Tarea > childElement = nuevo Nodo < Tarea > ( childTask );

elementos infantiles . agregar (childElement );

getRecursive ( childElement , tree );

taskElement . setChildren ( childElements );

Ejemplo 3
Dado un árbol binario, BTree, implementar un método en éste que devuelva la altura del
mismo.

public class BTree<E> {

static class BNode<E> {

private E info;

private BNode<E> left;

private BNode<E> right;

BNode(E info) {

this(info, null, null);

BNode(E info, BNode<E> l, BNode<E> r) {

this.info = info;

left = l;

right = r;

}
E getInfo() {

return info;

BNode<E> getLeft() {

return left;

BNode<E> getRight() {

return right;

void setInfo(E info) {

this.info = info;

void setLeft(BNode<E> left) {

this.left = left;

void setRight(BNode<E> right) {

this.right = right;

void insert(BNode<E> tree, int side) throws BTreeException {

if (side == LEFT_SIDE) {

if (left == null) {

left = tree;

} else {

throw new BTreeException("A non-empty tree already exists");

} else if (side == RIGHT_SIDE) {

if (right == null) {

right = tree;
} else {

throw new BTreeException("A non-empty tree already exists");

} else {

throw new BTreeException("Incorrect side");

BNode<E> extract(int side) throws BTreeException {

BNode<E> subtree;

if (side == LEFT_SIDE) {

subtree = left;

left = null;

} else if (side == RIGHT_SIDE) {

subtree = right;

right = null;

} else {

throw new BTreeException("Incorrect side");

return subtree;

int size() {

int size = 1;

if (left != null) {

size += left.size();

if (right != null) {

size += right.size();

return size;
}

int height() {

int hl = -1;

int hr = -1;

if (left != null) {

hl = left.height();

if (right != null) {

hr = right.height();

return 1 + Math.max(hl, hr);

void preorder() {

System.out.println(info);

if (left != null) {

left.preorder();

if (right != null) {

right.preorder();

void inorder() {

if (left != null) {

left.inorder();

System.out.println(info);

if (right != null) {

right.inorder();
}

void postorder() {

if (left != null) {

left.postorder();

if (right != null) {

right.postorder();

System.out.println(info);

/* ********************************************** */

public static final int LEFT_SIDE = 0;

public static final int RIGHT_SIDE = 1;

protected BNode<E> root;

public BTree() {

root = null;

public BTree(E info) {

root = new BNode(info);

public BNode<E> getRoot() {

return root;

public void setRoot(BNode<E> root) {

this.root = root;

}
public void insert(BTree<E> tree, int side) throws BTreeException {

root.insert(tree.getRoot(), side);

public int size() {

int size = 0;

if (root != null) {

size = root.size();

return size;

public int height() {

int h = -1;

if (root != null) {

h = root.height();

return h;

public void preorder() {

if (root != null) {

root.preorder();

public void inorder() {

if (root != null) {

root.inorder();

public void postorder() {


if (root != null) {

root.postorder();

public class BTreeException extends Exception {

public BTreeException(String mensaje) {

super(mensaje);

Ejemplo 4
Dado un árbol binario, BTree, implementar un método en éste que devuelva el
número de nodos que tiene.

public class TestNumNodes {

public TestNumNodes() {

public static void main(String args[]) {

BTree tree;

try {

tree = new BTree("Tres");

BTree subarbol = new BTree("tristes");

tree.insert(subarbol, BTree.LEFT_SIDE);

BTree temporal = new BTree("tigres");

tree.insert(temporal, BTree.RIGHT_SIDE);

temporal = new BTree("com\355an");

subarbol.insert(temporal, BTree.LEFT_SIDE);
temporal = new BTree("trigo");

subarbol.insert(temporal, BTree.RIGHT_SIDE);

} catch (BTreeException ex) {

System.out.println(ex.getMessage());

return;

System.out.println("------------------");

System.out.println((new StringBuilder())

.append("Num Nodos Arbol Binario = ").append(tree.size()).toString());

System.out.println("------------------");

Arboles Binarios
Ejercicio nº1:

El recorrido en preorden de un determinado árbol binario es: GEAIBMCLDFKJH y en inorden


IABEGLDCFMKHJ .Resolver:

A) Dibujar el árbol binario.


B) Dar el recorrido en postorden.

I B A E D L F C H J K M G.

C) Diseñar una función para dar el recorrido en postorden dado el recorrido en preorden e
inorden y escribir un programa para comprobar el resultado del apartado anterior.

#include < stdio.h>


#include < stdlib.h>
#include < string.h>

char *preorden="GEAIBMCLDFKJH";
char *inorden="IABEGLDCFMKHJ";
char *postorden;

/*---------------------------------------*/

void post(char *pre,char *in,char *pos,int n)


{
int longIzqda;

if(n!=0){
pos[n-1]=pre[0];
longIzqda=strchr(in,pre[0])-in;
post (pre+1,in,pos,longIzqda);
post (pre+1+longIzqda,in+1+longIzqda,pos+longIzqda,n-1-longIzqda);
}
}

/*----------------------------------------*/

int main(int argc,char *argv[])


{
int aux;

aux=strlen(preorden);
postorden=(char *)malloc(aux*sizeof(char));
if (postorden){
printf("El preorden es: %s\n",preorden);
printf("El inorden es: %s\n",inorden);
post(preorden,inorden,postorden,aux);
postorden[aux]='\0';
printf("El postorden calculado es: %s\n",postorden);
free(postorden);
}
else{
fprintf(stderr,"Error: Sin memoria\n");
return 1;
}

return 0;

Ejercicio nº2:
Implementar una función no recursiva para recorrer un árbol binario en inorden.

#include < pilas.h>


#include < arbolesB.h>

/*---------------------------------------*/

void inordenNR(ArbolB T,void (* EscribirElemento)(void *),int tamano)


{
NodoB nodoActual,aux;
void *et;
Pila p;
int fin;
int faltaHD; /*Indica si falta el hijo derecho*/

p=CrearPila(sizeof(NodoB));
et=malloc(tamano);
if(!et){
.... /*Error:Sin memoria*/
}

aux=NODOB_NULO;
Push(&aux,p);
nodoActual=RaizB(T);
fin=0;
while(!fin){
while(nodoActual!=NODOB_NULO){
Push(&nodoActual,p);
nodoActual=HijoIzqdaB(nodoActual,T);
}
Tope(&nodoActual,p);
Pop(p);
if (nodoActual!=NODOB_NULO){
EtiquetaArbolB(et,nodoActual,T);
(*EscribirElemento)(et);
nodoActual=HijoDrchaB(nodoActual,T);
}
else fin=1;
}

free(et);
DestruirPila(p);
}

Ejercicio nº3:

Escribir una función que realice la reflexión de un árbol binario.

void Refleja(ArbolB T)
{
ArbolB Ti,Td;

if(T!=ARBOLB_VACIO){
Ti=PodarHijoIzqdaB(RaizB(T),T);
Td=PodarHijoDrchaB(RaizB(T),T);
Refleja(Ti);
InsertarHijoDrchaB(RaizB(T),Ti,T);
Refleja(Td);
InsertarHijoIzqdaB(RaizB(T),Td,T);
}
}

Ejercicio nº4:

Escribir una función recursiva que encuentre el número de nodos de un árbol binario.

//El algoritmo es muy sencillo considerando que el número de nodos de un árbol binario es el número de
nodos del hijo a la izquierda más el de su hijo a la derecha más 1. 

int numero(NodoB n,ArbolB T)


{
if (n==NODOB_NULO)
return 0;
else
return 1+numero(HijoIzqdaB(n,T),T)+numero(HijoDrchaB(n,T),T);
}

//Para calcular el número de nodos de un árbol T se haría mediante la llamada número (RaizB(T),T).
Ejercicio nº5:

Escribir una función recursiva que encuentre la altura de un árbol binario.

//La altura de un árbol T es uno más el máximo de alturas de los subárboles izquierdo y derecho(La altura de
un árbol nulo está indefinida).

#define MAXIMO(a,b) ((a) < (b)?(b):(a))

int altura(NodoN n,ArbolB T)


{
if(n==NODOB_NULO)
return -1;
else
return 1+MAXIMO(altura(HijoIzqdaB(n,T),T),altura(HijoDrchaB(n,T),T));
}

Recorrido por Arboles


Ejemplo 1: realice los diferentes recorridos sobre árboles de las figuras 12.5a, 12.5b y 12.5c.
Ejemplo 2

Recorrido Pre Orden (RID)


El recorrido en Pre Orden del árbol es el siguiente: 15, 6, 4, 10, 20, 17, 22
Recorrido En Orden(IRD)
El recorrido en En Orden del árbol es el siguiente: 4, 6, 10, 15, 17, 20, 22
Recorrido Post Orden(IDR)
El recorrido en Post Orden del árbol es el siguiente: 4, 10, 6, 17, 22, 20, 15

Ejemplo 3
Pre Orden (RID) 18, 12, 5, 9, 28, 20, 35
En Orden (IRD) 5, 9, 12, 18, 20, 28, 35
Post Orden (IDR) 9, 5, 12, 20, 35, 28, 18

Ejemplo 4

Вам также может понравиться