Está en la página 1de 12

EJEMPLO 20.1. .

Nivel 0 A Rama AF

Nivel 1 B E F
Rama FI

Nivel 2 C D G H I

padres: A, B, F Hojas: C, D, E, G,
hijos: B, E, F, C, D,G, H, H, I
Ihermanos: {B, E, F}, {C, D}, {G, H, I}

EJEMPLO 20.2

A
A

C
completo
B
B C
D E F G lleno
D E F G
H I J K .

EJEMPLO 20.3

* *

+ -
+ -
X * A B

X Y A B
Y Z
rbol de expresin (X+Y)*(A-B) rbol de expresin (X+(Y*Z))+(A-B)

EJEMPLO 20.4

1
* *
+ *

+
A *-
+ C +
* C-*
A
B B-
A B A +
Z+

X Y
C D
(A+B)*C A+B*(-(C+D)) (A*(X+Y))*C

EJEMPLO 20.5

*
A *
A *
A
Camino A, B, D, E, C, F Y G Camino D,B,E,A,F,C Y G Camino D,E,B,F,G,C y A
1 4 7
+
B -*
C +
B -*
C +
B -*
C
2 5 2 6 3 6
D E F G D E F G D E F G
3 4 6 7 1 3 5 7 1 2 4 5

Preorden Inorden Postorden

EJEMPLO 20.6.

55 30 menor que 55 5 12
41 mayor que 30
75 mayor que 55
30 75 4 7
85 mayor que 75 8 16
1 6 8
4 41 85 7 11
3 7 9

EJEMPLO 20.7 .

30 30
10 40 10 40

8 25 32 8 25 32

12 12

14

EJEMPLO 20.8

2
30 30 30

5 40
5 5 40
40

2 80 2 36 80
2
(a) Insercin de 80 (b) Insercin de 36

EJEMPLO 20.9

30 30

5 40 5 40

2 85
2 36 85

EJEMPLO 20.10..

4 7

1 6 8

3 7 9

EJEMPLO 20.11.

40 40

20 60 20 55

10 30 50 70
10 30 50 70

45 55
45 54
54

EJERCICIO 20.1

3
La primera estructura no es un rbol binario ya que el nodo cuyo contenido es B tiene tres hijos
y le mximo nmero de hijos de un rbol binario es dos. Esta estructura es un un rbol general.
La segunda no es un rbol binario porque hay dos caminos distintos para ir al nodo F y por tanto
no se expresa la jerarqua de la definicin de rbol un rbol en general y de un binario en
particular. La tercera por la misma razn que la segunda no es un rbol binario.

EJERCICIO 20.2

a) Su altura es cuatro.
b) El rbol est equilibrado ya que la diferencia de las alturas de los subrboles izquierdo y
derecho es como mximo uno.
c) Los nodos hoja son: W, T, X, V.
d) El predecesor inmediato (padre) del nodo U es el nodo que contiene R.
e) Los hijos del nodo R son U y V.
f) Los sucesores del nodo R son U, V, X.

EJERCICIO 20.3
Recorrido RDI : P, R, V, U, X, Q, T, S, W.
Recorrido DRI : V, R, X, U, P, T, Q, S, W.
Recorrido DIR : V, X, U, R, T, W, S, Q.

EJERCICIO 20.4

E Y

E Y
T

R M T

I II
C

A O

R
N

M Y

F S

E
E L
R

III IV

4
b) los recorridos en inorden, preorden y postorden de cada uno de los rboles son:

Inorden: E, M, R, T, Y Inorden: E, M, R, T, Y
Preorden: M, E, Y, T, R Preorden: R, E, M, Y, T
Prostorden: E, R, T, Y, M Prostorden: M, E, T, Y, R
I II
Inorden: E, M, T, R,Y Inorden: A, C, E, F, K, L, N, O,
Preorden: T, M, E, Y, R R, S
Prostorden: E, M, R, Y, T Preorden: C, A, O, N, F, E, L, K,
R, S
Prostorden: A, E, K, L, F, N, S, R,
O, L
III IV

EJERCICIO 20.5:

/ +

A +
-
+

/
B

A B C D

C D

(A+B) / (C-D) A+B+C/D

-
X
A
/

A
I
- +

A B +

+
B - E F
C D

E F
C D (A+B) * ((C+D) / (E+F))

A- (B- (C-D) / (E+F)

5
/

-
-

A
B
* /

C D E F

(A-B) / ((C*D) (E/F))

EJERCICIO 20.6.

A
P

D Z

L
F

H
G
K
W

PREORDEN: A, D, F, G, H, K, L, P, Q, R, W, Z.
INORDEN: G, F, H, K, O, L, A, W, R, Q, P, Z.

PROBLEMA 20.1

typedef int Telemento;


class Nodo;
class Arbol
{
protected:
Nodo *a; // puntero a la clase Nodo
public:
Arbol Ohi(); // Obtener hijo izquierdo
Arbol Ohd(); // Obtener hijo derecho
Arbol Phi(Arbol a1); // Poner hijo izquierdo
Arbol Phd(Arbol a1); // Poner hijo derecho
Telemento Oraiz(); // Obtener elemento raz
void Praiz(Telemento e1); // Poner elemento raz
Arbol(); // constructor
~ Arbol(); //destructor

6
};

class Nodo
{
private:
Telemento e; // elemento que se almacena
Arbol hi, hd; // hijo izquierdo y derecho son rboles
friend class Arbol; // Arbol es clase amiga de Nodo
public:
Nodo (Arbol ai, Telemento x, Arbol ad); // contructor
~ Nodo(){}; //destructor
};

Arbol Arbol::Ohi()
{
return a->hi;
};

Arbol Arbol::Ohd()
{
return a->hd;
};

Arbol Arbol::Phi(Arbol a1)


{
a->hi = a1;
};

Arbol Arbol::Phd(Arbol a1)


{
a->hd = a1;
};

Telemento Arbol::Oraiz()
{
return a->e;
};

void Arbol::Praiz(Telemento e1)


{
a->e = e1;
};
Arbol::Arbol()
{
a = NULL;
};

Arbol::~Arbol()
{
if (a)
delete a;
}

Nodo::Nodo (Arbol ai, Telemento x, Arbol ad)


{
e = x;
hi = ai;
hd = ad;
};

7
PROBLEMA 20.2

Arbol::Arbol(const Arbol & arb)


{ // constructor de copia
if (arb.a == NULL)
a = NULL;
else
a = new Nodo(arb.a->hi, arb.a->e, arb.a->hd);
//llama recursivamente al constructor por copia
}

PROBLEMA 20.3

void Arbol:: Copiar ( Arbol & a1)


{
if(a)
{
a1.a = new Nodo (Arbol(),a->e, Arbol()); //copia raz
a->hi.Copiar(a1.a->hi); // copiar hijo izquierdo
a->hd.Copiar(a1.a->hd); // copiar el hijo derecho
}
else; //sin hacer hada funciona el constructor. a1 = NULLL
}

PROBLEMA 20.4

const Arbol& Arbol::operator = (const Arbol& arb)


{ // sobrecarga del operador de asignacin
if (a != NULL)
delete a; // hay que elminar el rbol antes de copiar
if (arb.a == NULL)
a = NULL;
else
a = new Nodo(arb.a->hi, arb.a->e, arb.a->hd);
//llama recursivamente al constructor por copia
return *this;
}

PROBLEMA 20.5

void Arbol:: Espejo ( Arbol & a1)


{
if(a)
{ a1;
a1.a = new Nodo (Arbol(),a->e, Arbol());
a->hi.Espejo(a1.a->hd);
a->hd.Espejo(a1.a->hi);
}
else;
}

PROBLEMA 20.6

void Arbol::IRD() // Recorrido en inorden


{
if (a !=NULL)
{
a->hi.IRD();

8
cout << a->e <<" XXX" << endl;
a->hd.IRD();
}
}

void Arbol::IDR()
{
if (a !=NULL)
{
a->hi.IDR();
a->hd.IDR();
cout << a->e <<" XXX" << endl;
}
}

void Arbol::RID()
{
if (a !=NULL)
{
cout << a->e <<" XXX" << endl;
a->hi.RID();
a->hd.RID();
}
}

PROBLEMA 20.7

int Arbol::Cuantos()
{
if (a!= NULL)
return 1+ a->hi.Cuantos() + a->hd.Cuantos();
else
return 0;
}

PROBLEMA 20.8

int Arbol::CuantasH()
{
if (a!= NULL)
if (a->hi.a == NULL && a->hi.a == NULL)
return 1;
else
return a->hi.CuantasH() + a->hd.CuantasH();
else
return 0;
}

PROBLEMA 20.9

void Arbol::NodosNivel(int n)
{
if (a)
if (n == 1)
cout << a->e ;
else
{
a->hi.NodosNivel(n - 1);

9
a->hd.NodosNivel(n - 1);
}
}

PROBLEMA 20.10

void Arbol::RecorreMayores(Telemento e)
{
if (a)
{
if(a->e > e)
cout << a->el << endl;
a->hi.RecorreMayores(e);
a->hd.RecorreMayores(e);
}
}

PROBLEMA 20.11

void Arbol::AnadeA (Telemento x)


{
if (a == NULL)
a = new Nodo (Arbol(), x, Arbol());
else
if (a->e > x)
a->hi.AnadeA(x);
else if (a->e < x)
a->hd.AnadeA(x);
else; // tratamiento de repeticiones rep(x)
}

void Arbol::AnadeAI (Telemento x) // aade iterativamente


{
Nodo *Ant = NULL, *nuevo, *pos = a;
bool enc = false;

while (!enc && pos != NULL) // bsqueda


{
if (pos->e == x)
enc = true; // encontrado
else
{
Ant = pos;
if( pos->e < x )
pos = pos->hd.a; // avanza hacia la derecha
else
pos = pos->hi.a; // avanza hacia la izquierda
}
}
if (enc)
//repe(x); tratamiento de claves repetidas
else //insercin del nodo
{
nuevo = new Nodo(Arbol(),x,Arbol());
if (Ant == NULL)// es la raz
a = nuevo;
else
if (Ant->e < x) // es un hijo derecho de Ant
Ant->hd.a = nuevo;
Else // es un hijo izquierdo de Ant

10
Ant->hi.a = nuevo;
}

PROBLEMA 20.12

void Arbol:: BorrarA (Telemento x)


{
if (a == NULL)
cout << "error en borrado no est " << endl;
else
if (a->e < x)
a->hd.BorrarA(x); //llamada a la derecha
else if (a->e > x)
a-> hi.BorrarA(x); //llamada a la izquierda
else if (a-> hi.a == NULL) // no tiene hijo izquierdo
{
Nodo * aborrar;
aborrar = a;
a = a->hd.a; // enlaza con su hijo derecho
aborrar->hd = Arbol();// para que no se propague el delete
delete aborrar;
}
else if( a->hd.a == NULL) // no tiene hijo derecho
{
Nodo * aborrar;
aborrar = a;
a= a->hi.a; // enlaza con su hijo izjierdo
aborrar->hi = Arbol();// para que no se propague el delete
delete aborrar;
}
else // dos hijos predecesor inmediato
a->hi.BorP(a->e);// avanza uno izquierda y recibe valor en a->e
}

void Arbol::BorP( Telemento &x)


{ // todo a la derecha
if ( a->hd.a == NULL)// si no tiene hijo derecho fin recursividad
{
Nodo * aborrar = a;
a = a->hi.a; // enlaza con su hijo izquierdo
aborrar-> hi= Arbol();
x = aborrar-> e ; // retorna el valor a raz original
delete aborrar;
}
else
a->hd.BorP (x); // llamada recursiva
}

void Arbol::BorrarAI(Telemento x)
{
Nodo * Ant = NULL, *aborrar, *pos = a;
bool enc = false;
while (!enc && pos != NULL) // no encontrado y quede rbol
{
if (pos->e == x)
enc = true; // encontrado
else
{
Ant = pos; // quedarse con el anterior

11
if( pos->e < x )
pos = pos->hd.a; // avanza a la derecha
else
pos = pos->hi.a; // avanza a la derecha
}
}
if (enc)
{
if ( pos-> hd.a == NULL) // no hijo derecho
{
if (Ant) // no es la raz
if (Ant->hd.a == pos) // pos es hijo derecho de Ant
Ant->hd.a = pos->hi.a;
else
Ant->hi.a= pos->hi.a;
else // es la raz
a = pos->hi.a;
pos->hi = Arbol() ;
delete pos;
}
else if ( pos-> hi.a ==0) // no hijo izquierdo
{
if (Ant) // no es la raz
if (Ant->hd.a == pos) //pos es hijo izquierdo de Ant
Ant->hd.a = pos->hd.a;
else
Ant->hi.a = pos->hd.a;
else
a = pos->hd.a;
pos->hd= Arbol();
delete pos;

}
else // dos hijos predecesor inmediato
a->hi.BorPI(a->e); // uno a la izquierda, y todo derecha
}
else
cout << " no encontrado";
}

void Arbol::BorPI(Telemento &x)


{
Nodo *Ant = NULL, *Aux = a;
while( Aux->hd.a) // bsqueda a la derecha
{
Ant = Aux;
Aux = Aux->hd.a;
}
if (Ant == NULL) // No tena hijo derecho
a = Aux->hi.a; // enlaza el padre
else
Ant->hd.a = Aux->hi.a; // enlaza hijo derecho de Ant con
//izquiedo de aux
Aux ->hi= Arbol();
x = Aux->e;
delete Aux;
}

12