You are on page 1of 60

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 27

3.

Estructuras de Datos en Memoria Principal

3.1

Pilas o Colas LIFO

3.1.1 Definicin
Una estructura de datos en que las inserciones y supresiones pueden hacerse slo por un
extremo, es decir, slo puede crecer o decrecer por un extremo.
E l im in a r

A d i c io n a r

Figura 9
Esta estructura de datos modela una propiedad encontrada frecuentemente en la vida
real. Por ejemplo en un restaurante, donde se colocan los platos uno encima de otro.
Cuando llega un plato nuevo lo colocan sobre los existentes y cada vez que se necesita
utilizar uno se toma el ltimo que fue colocado. Otro caso es el de coches en una pista no
circular. Libros sobre el piso.
Esta estructura se suele llamar LIFO, como acrnimo de las palabras inglesas Last
In, First Out (ltimo en entrar, primero en salir).
En cualquier momento el nico elemento visible de la estructura es el ltimo
elemento que se coloc. As se define el TOPE de la pila como el punto donde se encuentra
dicho elemento.

Tope

Figura 10
Si una pila no tiene elementos, se dice que la pila est vaca, y no tiene sentido hablar
del tope.
Se define la longitud de una pila como el nmero de elementos que la conforman.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 28

3.1.2 Operaciones sobre Pilas


Las operaciones son las siguientes:

Crear una pila vaca (CREATE)


Insertar un elemento en el tope de la pila (PUSH)
Eliminar un elemento ubicado en el tope de la pila (POP)
Retornar el elemento ubicado en el tope de la pila (TOP)
Determinar si la pila est vaca (ISEMPTY)
Determinar la longitud de la pila (SIZE)

3.1.3 Especificacin como TAD


Una de las formas de entender cmo trabaja este tipo abstracto de dato es a travs de
su especificacin.
Stack
Operaciones
create: Stack
push: Element, Stack Stack
top: Stack Element
pop: Stack Stack
isEmpty: Stack Boolean
size: Stack Integer
Axiomas
top(push(e, s)) == e
pop(push(e, s)) == s
size(create) == 0
size(push(e, s)) == size(s) + 1
isEmpty(create) == true
isEmpty(push(e, s)) == false
3.1.4 Representacin de una Pila Mediante Arreglos
Cuando se quiere representar una pila mediante arreglos, se debe definir el tamao
mximo de la pila, adems de un apuntador (tope: entero) que indica la cima o el tope de la
pila, es decir, dnde se debe insertar el prximo elemento. La representacin grfica de una
pila es la siguiente:

Arreglo: tamao mximo n=5

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 29

Al utilizar arreglos para implementar pilas, se tiene la limitacin del espacio de


memoria reservada. Una vez establecido un mximo de capacidad para la pila, ya no es
posible insertar ms elementos.
Inicialmente el tope debe estar en un extremo del arreglo. De acuerdo a esto existen
dos formas de implementar el arreglo: creciente hacia abajo o creciente hacia arriba:

Creciente
hacia abajo
Pila vaca: tope = -1
Pila llena : tope = n-1

Creciente
hacia arriba
Pila vaca: tope = n
Pila llena : tope = 0

Para el caso de las pilas crecientes hacia abajo, la estructura de datos es la siguiente:
typedef struct{
int tope;
tipo_tamano tamano;
tipo_elemento ele[MAX];
}pila_a;
Las operaciones son las siguientes:

1.- Creacin de una Pila

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

pila_a createa(){
pila_a pilaarray;
pilaarray.tope = -1;
pilaarray.tamano = 0;
return pilaarray;
}
2.- Insercin de un Dato en la Pila
pila_a pusha(tipo_elemento ele, pila_a pila){
if (sizea(pila) != MAX)
{
pila.tope ++;
pila.ele[pila.tope] = ele;
pila.tamano++;
}
else
printf("\nPila Llena\n");
return pila;
}
3.- Eliminacin de un Dato de la Pila
pila_a popa(pila_a pila){
if (!isemptya(pila)) {
pila.tope--;
pila.tamano--;
}
else
printf("\nPila Vacia\n");
return pila;
}
4.- Retornar el Elemento situado en el Tope
tipo_elemento topa(pila_a pila){
if (!isemptya(pila))
return pila.ele[pila.tope];
else {
printf("\nPila Vacia\n");
return 0;
}
}
5.- Determinar si la Pila est Vaca
unsigned int isemptya(pila_a pila){
if (pila.tope == -1)
return TRUE;
Material preparado por PEDRO ROSSEL CID

Pgina 30

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 31

else
return FALSE;
}
6.- Determinar el Tamao de la Pila
tipo_tamano sizea(pila_a pila){
return pila.tamano;
}

3.1.5 Representacin de una Pila Mediante Punteros


A diferencia de la implementacin de pilas con arreglos, en teora la implementacin
con punteros supone un espacio ilimitado. Si bien esto en la prctica no es verdad, dado que
la memoria de un computador no es infinita, s da una maniobrabilidad mayor el usar
punteros, pues no estamos limitados a priori en el tamao de las pilas.
En este caso, tambin es necesario definir la estructura de datos.
struct pila_p{
tipo_elemento ele;
tipo_tamano tamano;
struct pila_p *enlace;
};
Las operaciones son las siguientes:
1.- Creacin de una Pila
struct pila_p* createp(){
struct pila_p *aux;
aux = (struct pila_p *)malloc(sizeof(struct pila_p));
aux = NULL;
return aux;
}

2.- Insercin de un Dato en la Pila


struct pila_p* pushp(tipo_elemento ele, struct pila_p *pila){
struct pila_p *aux;
aux = (struct pila_p *)malloc(sizeof(struct pila_p));
aux->ele = ele;
aux->enlace = pila;
if (!isemptyp(pila))
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

aux->tamano=pila->tamano + 1;
else
aux->tamano = 1;
pila = aux;
return pila;
}
3.- Eliminacin de un Dato de la Pila
struct pila_p* popp(struct pila_p *pila){
struct pila_p *aux;
if (!isemptyp(pila))
{
aux = pila;
aux->tamano=pila->tamano - 1;
pila = pila->enlace;
free(aux);
}
else
printf("\nPila Vacia\n");
return pila;
}
4.- Retornar el Elemento situado en el Tope
tipo_elemento topp(struct pila_p *pila)
{
if (!isemptyp(pila))
return pila->ele;
else{
printf("\nPila Vacia\n");
return 0;
}
}
5.- Determinar si la Pila est Vaca
unsigned int isemptyp(struct pila_p *pila){
if (pila == NULL)
return TRUE;
else
return FALSE;
}
6.- Determinar el Tamao de la Pila

Material preparado por PEDRO ROSSEL CID

Pgina 32

Algoritmos y Estructuras de Datos, Apuntes de Clases

tipo_tamano sizep(struct pila_p *pila){


if (!isemptyp(pila))
return pila->tamano;
else
return 0;
}
3.1.6 Ejemplos
1.- Se tienen variables para las pilas:
pila_a pilaa;
struct pila_p *pilap;
Y un programa principal, como el siguiente
int main()
{
// Pilas en puntero
printf("\n PUNTEROS");
printf("\n");
pilap = createp();
pilap = pushp(1, pilap);
pilap = pushp(2, pilap);
printf("\nTope = %d ",topp(pilap));
printf("\nSize = %d ",sizep(pilap));
pilap = popp(pilap);
printf("\nTope = %d ",topp(pilap));
printf("\nSize = %d ",sizep(pilap));
pilap = pushp(6, pilap);
pilap = pushp(7, pilap);
printf("\nTope = %d ",topp(pilap));
printf("\nSize = %d ",sizep(pilap));
//
// Pilas en arreglo
//
printf("\n");
printf("\n ARREGLOS");
printf("\n");
pilaa = createa();
pilaa = pusha(1, pilaa );
pilaa = pusha(2, pilaa);
printf("\nTope = %d ",topa(pilaa));
printf("\nSize = %d ",sizea(pilaa));
pilaa = popa(pilaa);
printf("\nTope = %d ",topa(pilaa));
printf("\nSize = %d ",sizea(pilaa));
Material preparado por PEDRO ROSSEL CID

Pgina 33

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 34

pilaa = pusha(6, pilaa);


pilaa = pusha(7, pilaa);
printf("\nTope = %d ",topa(pilaa));
printf("\nSize = %d ",sizea(pilaa));
return 0;
}
La salida de este programa sera la siguiente:
PUNTEROS
Tope = 2
Size = 2
Tope = 1
Size = 1
Tope = 7
Size = 3
ARREGLOS
Tope = 2
Size = 2
Tope = 1
Size = 1
Tope = 7
Size = 3

2.- Suponga que se tiene una pila, llena con nmeros enteros. La cantidad de elementos de
esta pila no se conoce de antemano.
Se pide realizar un programa en C, que:

pida ingresar por teclado un nmero entero.


a partir de la pila inicial, y con el nmero que se ingresar previamente, genere dos
pilas, una que contenga los nmeros mayores o iguales ( >= ) al nmero ingresado
(su tope ser la variable PILAMAYOR), y otra que contenga los nmeros menores
( < ) al nmero ingresado (su tope ser la variable PILAMENOR).

NOTA:
a) Slo se aceptan las operaciones vlidas para pilas.
b) No es necesario que las pilas queden internamente ordenadas.
.
struct pila_p *pilap, *pilamayor, *pilamenor;

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 35

.
pilap = createp();
.
.
pilamayor = createp();
pilamenor = createp();
.
while (!isemptyp(pilap))
{
if (topp(pilap)>=nn)
pilamayor = pushp(topp(pilap), pilamayor);
else
pilamenor = pushp(topp(pilap), pilamenor);
pilap = popp(pilap);
}
.
3.- Escriba un programa en C que utilice Pilas de caracteres, para procesar cada uno de los
caracteres de una cadena con la finalidad de verificar el equilibrio de parntesis, llaves y
corchetes existentes en esta cadena.
Cadenas equilibradas son:

((1 + 5) *9 + 2);
{[(1 + 2)*(3 / 2)]*(3 1)};

Cadenas desequilibradas son:

([1+5)*9+2);
[2 + (4 *5) 4;

Notas:
Use un arreglo de mximo tamao 20 para introducir la cadena, es decir, un carcter
por posicin del arreglo (excepto el punto y coma ;).
Use el punto y coma para determinar cuando termina la cadena.
A partir del arreglo traspase los datos necesarios a una o ms pilas para realizar lo
que se pide. Debe utilizar (no crear) SOLO las operaciones permitidas para pilas.
int main()
{
char cadena[20], caracter;
int i,j, equi;
struct pila_p *pilap, *pilaaux;
i = 0;
printf("\n");
do{
printf("\nIngrese caracter de la cadena (; para salir) = ");
scanf("%c", &caracter);
fflush(stdin);
if (caracter != ';')

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 36

{
cadena[i] = caracter;
i++;
}
}while ((caracter != ';')&&(i <=19));
for (j=0; j<=(i-1); j++)
printf("%c",cadena[j]);
printf("\n");
pilap = createp();
for (j=0; j<=i; j++)
if ((cadena[j] == '(' ) ||
(cadena[j] == '[' ) ||
(cadena[j] == '{' ) ||
(cadena[j] == ')' ) ||
(cadena[j] == ']' ) ||
(cadena[j] == '}' ) )
pilap = pushp(cadena[j], pilap);
pilaaux = createp();
equi = TRUE;
while ((!isemptyp(pilap)) && (equi == TRUE))
{
if ((topp(pilap) == ')') || (topp(pilap) == ']') || (topp(pilap)
== '}'))
{
pilaaux = pushp(topp(pilap), pilaaux);
pilap = popp(pilap);
}
else
if ((topp(pilap) == '(') && (!isemptyp(pilaaux)) &&
(topp(pilaaux) == ')'))
{
pilap = popp(pilap);
pilaaux = popp(pilaaux);
}
else
if ((topp(pilap) == '[') && (!isemptyp(pilaaux)) &&
(topp(pilaaux) == ']'))
{
pilap = popp(pilap);
pilaaux = popp(pilaaux);
}
else
if ((topp(pilap) == '{') && (!isemptyp(pilaaux)) &&
(topp(pilaaux) == '}'))
{
pilap = popp(pilap);
pilaaux = popp(pilaaux);
}

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 37

else
equi = FALSE;
}
if (equi == TRUE)
if (isemptyp(pilaaux))
printf("\nEquilibrado....\n");
else
printf("\nDesequilibrado....\n");
else
printf("\nDesequilibrado....\n");
system("pause");
return 0;
}

3.2

Filas o Colas FIFO

3.2.1 Definicin
Una estructura de datos en que las inserciones se hacen por un lado y las supresiones
se hacen por otro.

Entrada

Salida

Figura 11
El ejemplo tpico de una cola, es la fila de espera que hacemos mientras esperamos
atencin en alguna parte. Cuando llegamos nos colocamos al final, y esperamos a que
atiendan y salgan de la fila los que llegaron antes. No existe manera de llevar a un puesto
diferente del ltimo, ni esperar ser atendido y salir de la fila mientras estemos en un puesto
distinto del primero.
Este tipo de estructura lineal se conoce en la literatura como estructura FIFO, como
acrnimo de las palabras inglesas First In, First Out (primero en entrar, primero en salir).
En cualquier momento, los nicos elementos accesibles de la estructura son el primer
y el ltimo elemento. Definimos as FRENTE como el punto por donde son sacados los
elementos de la estructura. FINAL es el punto por donde se insertan nuevos elementos.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Frente

Pgina 38

Final

Figura 12
La longitud de la fila se define como el nmero de elementos que la conforman. Si la
longitud es cero, la cola est vaca.

3.2.2 Operaciones sobre Filas


Las operaciones son las siguientes:

Crear una fila vaca (CREATE)


Insertar un elemento en el final de la fila (PUSH)
Eliminar un elemento desde el frente de la fila (POP)
Retornar el elemento ubicado en el frente de la fila (FRONT)
Determinar si la fila est vaca (ISEMPTYQUEUE o ISEMTQ)
Determinar la longitud de la fila (SIZE)

3.2.3 Especificacin como TAD


La especificacin de este tipo abstracto de dato es la siguiente:

Queue
Operaciones
create: Queue
push: Element, Queue Queue
front: Queue Element
pop: Queue Queue
isEmpty: Queue Boolean
size: Queue Integer
Axiomas
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

front(push(e, q)) == if isEmpty(q) then e else front(q)


pop(push(e, q)) == if isEmpty(q) then q else push(e, pop(q))
size(create) == 0
size(push(e, q)) == size(q) + 1
isEmpty(create) == true
isEmpty(push(e, q)) == false

3.2.4 Representacin de una Fila Mediante Arreglos


typedef struct{
int frente;
int final;
tipo_tamano tamano;
tipo_elemento ele[MAX];
}fila_a;
fila_a filaa;
1.- Creacin de una Fila
fila_a createa(){
fila_a filaarray;
filaarray.frente = -1;
filaarray.final = -1;
filaarray.tamano = 0;
return filaarray;
}

2.- Insercin de un Dato en la Fila


fila_a pusha(tipo_elemento ele, fila_a fila){
if ((sizea(fila) != MAX) && (fila.final<(MAX-1)))
{
if (isemptya(fila))
fila.frente = 0;
fila.final ++;
fila.ele[fila.final] = ele;
fila.tamano++;
}
else
Material preparado por PEDRO ROSSEL CID

Pgina 39

Algoritmos y Estructuras de Datos, Apuntes de Clases

printf("\nFila Llena\n");
return fila;
}
3.- Eliminacin de un Dato de la Fila
fila_a popa(fila_a fila){
if (!isemptya(fila))
{
fila.frente++;
fila.tamano--;
}
else
printf("\nFila Vacia\n");
return fila;
}
4.- Retornar el Elemento situado en el Frente
tipo_elemento fronta(fila_a fila){
if (!isemptya(fila))
return fila.ele[fila.frente];
else{
printf("\nFila Vacia\n");
return 0;
}
}

5.- Determinar si la Fila est Vaca


unsigned int isemptya(fila_a fila){
if (sizea(fila) == 0)
return TRUE;
else
return FALSE;
}
6.- Determinar el Tamao de la Fila
tipo_tamano sizea(fila_a fila){
return fila.tamano;
}
Material preparado por PEDRO ROSSEL CID

Pgina 40

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 41

3.2.5 Representacin de una Fila Mediante Punteros


struct nodo{
tipo_elemento ele;
struct nodo *enlace;
};
typedef struct{
tipo_tamano tamano;
struct nodo *frente;
struct nodo *final;
}fila_p;
fila_p *filap;
Frente

Final

Figura 13
1.- Creacin de una Fila
fila_p* createp(){
fila_p *aux;
aux = (fila_p *)malloc(sizeof(fila_p));
aux->tamano = 0;
aux->frente = NULL;
aux->final = NULL;
return aux;
}
2.- Insercin de un Dato en la Fila
fila_p* pushp(tipo_elemento ele, fila_p *fila){
struct nodo *nodoaux;
nodoaux = (struct nodo *)malloc(sizeof(struct nodo));
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

nodoaux->ele = ele;
nodoaux->enlace = NULL;
if (!isemptyp(fila))
fila->final->enlace = nodoaux;
else
fila->frente = nodoaux;
fila->final = nodoaux;
fila->tamano=fila->tamano + 1;
return fila;
}
3.- Eliminacin de un Dato de la Fila
fila_p* popp(fila_p *fila){
struct nodo *aux;
if (!isemptyp(fila)) {
aux = fila->frente;
fila->frente = fila->frente->enlace;
if (isemptyp(fila))
fila->final = NULL;
fila->tamano=fila->tamano 1;
free(aux);
}
else
printf("\nFila Vacia\n");
return fila;
}
4.- Retornar el Elemento situado en el Frente
tipo_elemento frontp(fila_p *fila){
if (!isemptyp(fila))
return fila->frente->ele;
else{
printf("\nFila Vacia\n");
return 0;
}
}
5.- Determinar si la Fila est Vaca
unsigned int isemptyp(fila_p *fila){
if (fila->frente == NULL)
return TRUE;
else
return FALSE;
}
Material preparado por PEDRO ROSSEL CID

Pgina 42

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 43

6.- Determinar el Tamao de la Fila


tipo_tamano sizep(fila_p *fila){
return fila->tamano;
}
3.2.6 Ejercicio
Se tiene una fila representada mediante punteros, llamada FILADES. No se sabe
cuntos elementos posee; lo que s se sabe es que contiene nmeros enteros, que no
necesariamente estn ordenados.
Se pide: crear un programa en C que a partir de esta fila genere otra llamada
FILAORD, que est ordenada ascendentemente, es decir, que en el frente est el elemento
menor.
NOTA: Use slo las operaciones permitidas para filas. Se asume que en la fila original no
hay elementos repetidos.

int main()
{
tipo_elemento menor;
//
// Filas con PUNTEROS
//
printf("\n");
printf("\n Ejercicio Ordenar elementos de una Fila\n");
printf("\n");
filades = createp();
filaord = createp();
filaaux = createp();
// Insertar valores en la pila original
filades = pushp(6, filades );
filades = pushp(7, filades );
filades = pushp(4, filades );
filades = pushp(10, filades );
filades = pushp(8, filades );
filades = pushp(1, filades );
filades = pushp(18, filades );
filades = pushp(38, filades );
filades = pushp(25, filades );
filades = pushp(83, filades );
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

while(!isemptyp(filades))
{
// Buscar el menor de la fila. No trabaja con valore repetidos
menor = frontp(filades);
while(!isemptyp(filades))
{
if (frontp(filades)<menor)
menor = frontp(filades);
filaaux = pushp(frontp(filades), filaaux);
filades = popp(filades);
}
// Copia desde la filaaux a la filades
while(!isemptyp(filaaux))
{
filades = pushp(frontp(filaaux), filades);
filaaux = popp(filaaux);
}
// Copia el menor valor a la fila ordenada
filaord = pushp(menor, filaord);
// Saca de la fila original el menor valor
while(!isemptyp(filades))
{
if (frontp(filades) != menor)
filaaux = pushp(frontp(filades), filaaux);
filades = popp(filades);
}
// Copia desde la filaaux a la filades
while(!isemptyp(filaaux))
{
filades = pushp(frontp(filaaux), filades);
filaaux = popp(filaaux);
}
}
printf("\nElementos Ordenados...\n");
while(!isemptyp(filaord))
{
printf("%d ",frontp(filaord));
filaord=popp(filaord);
}
printf("\n\n");
return 0;
}

Material preparado por PEDRO ROSSEL CID

Pgina 44

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 45

3.2.7 Filas Circulares


La representacin de filas mediante arreglos no es muy eficiente, ya que cuando se
suprime el primer elemento, se requiere que la cola completa ascienda una posicin en el
arreglo, para as evitar tempranamente el overflow. Esto se debe a que se puede llegar a
una situacin en la que por ejemplo se tiene un nico elemento en el arreglo, por lo que la
variable tamano sera menor que MAX (N), y dicho elemento est situado en la posicin
(MAX 1). Si tratramos de ingresar un nuevo elemento no podramos, ya que si bien
existe espacio disponible, estaramos ocupando una posicin de memoria no reservada por el
compilador, por lo que sera una operacin no vlida.
La figura siguiente muestra una situacin intermedia, en la cual se han sacado
elementos de la fila. Por ello quedan espacios disponibles al inicio del arreglo.

Frente

Final

Figura 14
As se puede pensar en un arreglo circular, en la cual la fila se encontrar en algn
lugar del arreglo, como se ve en la figura siguiente.
N-2

Frente

N-1

1
2
Final

Figura 15
El tratamiento es un poco distinto ya que como veremos en los algoritmos, la casilla
cero (0) es una posicin que puede contener un elemento. Luego, la creacin de la cola
quedar como se muestra a continuacin, para que
FRENTE = FINAL = 0
no represente cola vaca.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 46

A continuacin se presentan la implementacin de las operaciones. Slo se describen


las que se deben modificar. Las operaciones FRONT, ISEMPTY y SIZE son las mismas que
para filas no circulares con arreglos.
1.- Creacin de una Fila Circular
fila_a createa(){
fila_a filaarray;
filaarray.frente = 0;
filaarray.final = 0;
filaarray.tamano = 0;
return filaarray;
}
2.- Insercin de un Dato en la Fila Circular
fila_a pusha(tipo_elemento ele, fila_a fila){
if ((sizea(fila) != MAX) )
{
fila.ele[fila.final] = ele;
fila.final = (fila.final + 1)%MAX;
fila.tamano++;
}
else
printf("\nFila Llena\n");
return fila;
}
3.- Eliminacin de un Dato de la Fila Circular
fila_a popa(fila_a fila){
if (!isemptya(fila))
{
fila.frente = (fila.frente + 1)%MAX;
fila.tamano--;
}
else
printf("\nFila Vacia\n");
return fila;
}
3.3

Listas Enlazadas

3.3.1 Definicin

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 47

Una lista es un conjunto de n 0 elementos o nodos de un tipo determinado x1, x2, ...
,xn organizados estructuralmente que reflejen las posiciones relativas de los mismos. Esto
quiere decir que existe un orden entre los nodos.
n es la longitud de la lista.
Si n = 0 se tiene una lista vaca, es decir no tiene elementos, y su longitud es cero.
Si n 1 se dice que:
x1 es el primer elemento (o nodo) de la lista
xn es el ltimo elemento (o nodo) de la lista
xk-1 precede a xk
Adems se dice que xi est en la posicin i dentro de la lista.

Figura 16
Las representaciones anteriores o tipo de almacenamiento dependern de al
especificacin del problema, o sea qu es lo que se quiere hacer.
3.3.2 Operaciones sobre Listas
1. Crear una lista vaca
2. Determinar el nmero de nodos (tamao) de la lista
3. Determinar si la lista es vaca o no
4. Insertar un nuevo nodo al inicio de la lista
5. Insertar un nuevo nodo antes o despus del k-simo nodo
6. Inserta un nodo al final de la lista
7. Accesar el k-simo nodo para obtener su contenido
8. Accesar el k-simo nodo para alterar su contenido
9. Eliminar el primer nodo de la lista
10. Eliminar el k-simo nodo
11. Eliminar un nodo que contiene un cierto valor
12. Eliminar el ltimo nodo de la lista
Dependiendo de la representacin y del lenguaje de programacin, estas operaciones
tendrn diferentes formas de hacerse.
Ejemplo
Insertar un nuevo nodo, en el k-simo nodo de la lista

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 48

Figura 12
Qu sucede si se desea insertar o eliminar un nodo ubicado:
al inicio de la lista?
aumenta el tiempo de acceso

al centro?
da lo mismo

al final?
disminuye el tiempo de acceso
Depende del problema; luego debe hacerse un estudio o anlisis de ste.
3.3.3 Otras definiciones
1. Dos listas lista1 y lista2 son iguales, si ambas estructuras tienen el mismo nmero de
componentes, y adems sus elementos son iguales uno a uno. Esto implica que el primer
elemento de la lista debe ser igual al primero de la otra lista y as sucesivamente. En
particular las listas vacas son iguales.
Ejemplo:
lista1= 8, 19, 34, 3
lista2= 7, 19, 34, 4
lista3= 8, 19, 34, 3
lista4= 8, 19, 3, 34
2. Se dice que una lista2 es sublista de lista1 si todos los elementos de lista2 se encuentran
en lista1, consecutivos y en el mismo orden.
Ejemplo:
lista5= 19, 34
lista6= 8, 19, 3
lista7= 34, 19

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 49

3. Una lista lista1 es ordenada cuando se define una relacin de orden R entre sus elementos.
Por ejemplo, la relacin de orden puede ser la de los nmeros naturales, la de los das de la
semana, la dada por el alfabeto, etc.
Ejemplo:
lista8= c, d, f, h, k
lista9= Lunes, Martes, Mircoles. Jueves, Viernes
lista10= 8, 9, 11,20
lista11= 23, 19, 15, 12, 7

3.3.4 Operaciones
Para las operaciones que se mostrarn a continuacin, se usar la siguiente
estructura:
struct nodo{
tipo_elemento ele;
struct nodo *enlace;
};
typedef struct{
tipo_tamano tamano;
struct nodo *actual;
}lista_p;
1.- Creacin de una Lista
lista_p* crear(){
lista_p *aux;
aux = (lista_p *)malloc(sizeof(lista_p));
aux->tamano = 0;
aux->actual = NULL;
return aux;
}
2.- Determinar el Tamao de la Lista
tipo_tamano tamano(lista_p *lista){
return lista->tamano;
}
3.- Determinar si la Lista est Vaca
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

unsigned int esvacia(lista_p *lista){


if (tamano(lista) == 0)
return TRUE;
else
return FALSE;
}

4.- Insertar un nuevo nodo al inicio de la Lista


lista_p* insertar_inicio(tipo_elemento ele, lista_p *lista){
struct nodo *nodoaux;
nodoaux = (struct nodo *)malloc(sizeof(struct nodo));
nodoaux->ele = ele;
nodoaux->enlace = lista->actual;
lista->actual = nodoaux;
lista->tamano=lista->tamano + 1;
return lista;
}

5.- Inserta un nodo al final de la lista


lista_p* insertar_final(tipo_elemento ele, lista_p *lista){
struct nodo *nodoaux, *aux;
nodoaux = (struct nodo *)malloc(sizeof(struct nodo));
nodoaux->ele = ele;
nodoaux->enlace = NULL;
if (!esvacia(lista))
{
aux = lista->actual;
while (aux->enlace != NULL)
aux = aux->enlace;
aux->enlace = nodoaux;
}
else
lista->actual = nodoaux;
lista->tamano=lista->tamano + 1;
return lista;
}

Material preparado por PEDRO ROSSEL CID

Pgina 50

Algoritmos y Estructuras de Datos, Apuntes de Clases

6.- Eliminar el primer nodo de la lista


lista_p* eliminar_inicio(lista_p *lista){
struct nodo *aux;
if (!esvacia(lista))
{
aux = lista->actual;
lista->actual = lista->actual->enlace;
free(aux);
lista->tamano=lista->tamano - 1;
}
else
printf("\nLista Vacia\n");
return lista;
}
7.- Eliminar el ltimo nodo de la lista
lista_p* eliminar_final(lista_p *lista){
struct nodo *aux;
int i;
if (!esvacia(lista))
{
aux = lista->actual;
for(i=1; i <(tamano(lista) - 1); i++)
aux = aux->enlace;
if (aux->enlace!=NULL)
{
free(aux->enlace);
aux->enlace = NULL;
}
else
{
free(aux);
lista->actual = NULL;
}
lista->tamano=lista->tamano - 1;
}
else
Material preparado por PEDRO ROSSEL CID

Pgina 51

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 52

printf("\nLista Vacia\n");
return lista;
}
3.4

Arboles

3.4.1 Arboles N-Arios


Los rboles son estructuras de datos, en las que existe una relacin jerrquica entre
los objetos o nodos constituyentes.
Existe una relacin de parentesco entre los nodos, en donde se asignan nombres
como Padre, Hijo, Antecesor, Sucesor, Ancestro, por ejemplo.
Formalmente se define un rbol de tipo T como una estructura homognea que es la
concatenacin de un elemento de tipo T, junto con un nmero finito de rboles disjuntos,
llamados Subrboles. En particular, un rbol puede ser la estructura vaca.
A continuacin se dan las caractersticas ms relevantes de los rboles:
1. Todo rbol no vaco tiene un nico nodo raz
2. Un nodo X es descendiente directo de un nodo Y, si el nodo X es apuntado por el
nodo Y. Se dice que X ES HIJO DE Y.
3. Un nodo X es antecesor directo de un nodo Y, si el nodo X apunta al nodo Y. Se
dice que X ES PADRE DE Y.
4. Se dice que todos los nodos que son descendientes directos (hijos) de un mismo
nodo (padre) son hermanos.
5. Todo nodo que no tiene ramificaciones se conoce con el nombre de terminal u hoja.
6. Todo nodo que no es raz ni hoja, se conoce como nodo interior.
7. Grado es el nmero de descendientes directos de un determinado nodo. Grado de un
rbol es el mximo grado de todos los nodos del rbol.
8. Nivel es el nmero de arcos que deben ser recorridos desde la raz al nodo ms uno.
Por definicin la raz tiene nivel 1.
9. Altura del rbol es el mximo nmero de niveles de todos los nodos del rbol.
Ejemplo
A

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 53

Figura 13

A es la raz del rbol


B es hijo de A
C es hijo de A
D es hijo de B
F es padre de J
F es padre de K
B y C son hermanos
G y H son hermanos
I, E, J, K, G, L son hojas o nodos terminales
B, D, F, C, H son nodos interiores
El grado del nodo A es 2
El grado del nodo G es 0
El grado del rbol es 3
El nivel del nodo A es 1
El nivel del nodo B es 2
El nivel del nodo L es 4
La altura del rbol 4

3.4.1.1 Caminamiento o Recorrido de rboles


Los caminamientos tambin se conocen con el nombre de ordenamiento. Los tres
ms importantes son:

Orden Previo (Preorden)


Orden Simtrico (Inorden)
Orden Posterior (Postorden)

A:

A1

A2

...

Figura 14

Material preparado por PEDRO ROSSEL CID

Ak

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 54

a) Preorden: El listado de los nodos de A est formado por la raz de A seguido de los
nodos de A1 en orden previo, luego por los nodos de A2 en orden previo y as
sucesivamente hasta los nodos de Ak en orden previo.
b) Inorden: Est constituido por los nodos de A1 en orden simtrico, seguido de n y luego
por los nodos de A2, ,Ak con cada grupo de nodos en orden simtrico.
c) Postorden: El listado de los nodos de A tiene los nodos de A1 en postorden, luego los
nodos de A2 en postorden y as sucesivamente hasta los nodos Ak en orden posterior y
por ltimo la raz n.
Ejemplo : Arbol de grado 2
A

Figura 15
Preorden
Inorden
Postorden

:A
:G
:K

B
K
G

D
D
D

G
B
B

Material preparado por PEDRO ROSSEL CID

K
A
H

C
H
I

E
E
E

H
I
J

I
C
F

F
F
C

J
J
A

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 55

3.4.1.2 Operaciones Sobre Arboles


A continuacin se mostrarn siete operaciones tpicas sobre rboles, las que pueden
ser implementadas en algn lenguaje de programacin como C.
1. PADRE(n, A): Esta funcin devuelve el Padre del nodo n en el rbol A. Si n es la
raz, que no tiene padre, se devuelve .De esta forma representa un nodo nulo,
que se usa como seal de que se ha salido del rbol.
2. HIJO_MAS_IZQUIERDA(n, A): Devuelve el hijo ms a la izquierda del nodo n en
el rbol A, y devuelve si n es una hoja, y por lo tanto no tiene hijos.
3. HERMANO_DERECHO(n, A): Devuelve el hermano a la derecha del nodo n en el
rbol A, el cual se define como m que tiene el mismo padre p que n, de forma que m
est inmediatamente a la derecha de n en el ordenamiento de los hijos de p.
4. ETIQUETA(n, A): Devuelve la etiqueta del nodo n en el rbol A. Sin embargo no se
requiere que haya etiquetas definidas para cada rbol.
5. CREAi(v, A0, A1, A2, , Ai): es un miembro de una familia infinita de funciones,
una para cada valor de i=0, 1, 2, . CREAi crea un nuevo nodo r con etiqueta v, y
le asigna i hijos que son las races de los rboles A0, A1, A2, , Ai en ese orden
desde la izquierda. Se devuelve el rbol con raz r. Si i=0, entonces r es a la vez una
hoja y la raz.
6. RAIZ(A): devuelve el nodo raz del rbol A, o si A es el rbol nulo.
7. ANULA(A): Convierte A en el rbol nulo.
La figura 28 muestra un rbol con etiquetas.
n1

n2

+
n3

a
n4

c
n5

n6

b
n7

Figura 16
3.4.1.3 Representacin de Arboles Mediante Encadenamiento
El uso de una representacin mediante punteros facilita la realizacin de las
operaciones de insercin y eliminacin de nodos en un rbol.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 56

En este caso, cada nodo puede considerarse compuesto por un campo para
almacenar el dato (info), y un conjunto de campos destinados a almacenar las direcciones de
inicio de los nodos hijos.

El problema que surge es que cada nodo puede tener un grado diferente.
La alternativa de solucin es limitar la cantidad de subrboles para los nodos a un
valor mximo.
En la figura siguiente se ve un rbol que tiene como mximo 3 subrboles.

Figura 17
En el caso de los rboles binarios (grado del rbol es dos), la representacin
encadenada ms utilizada, considera nodos formados por 3 campos:

HIJO_IZQ: Apunta al hijo izquierdo


INFO: Almacena el dato
HIJO_DER: Apunta al hijo derecho
Ejemplo
A

F
G

Figura 18

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 57

3.4.2 Arboles Binarios de Bsqueda


Es una estructura orientada a la representacin de conjuntos, cuyos elementos estn
clasificados en algn orden lineal. Esta estructura es til cuando se tiene un conjunto de
elementos de un universo muy grande.
Definicin
Un rbol binario de bsqueda es un rbol binario que es vaco o sus nodos estn
etiquetados con elementos de algn conjunto y que cumplen con la siguiente propiedad.
Propiedad de un Arbol Binario de Bsqueda
Todos los elementos almacenados en el subrbol izquierdo de cualquier nodo X, son
menores que el elemento almacenado en X, y todos los elementos almacenados en el
subrbol derecho de X son mayores que el elemento almacenado en X.
En un rbol binario de bsqueda las operaciones de insercin, eliminacin,
pertenencia y mnimo (o mximo) pueden realizarse en un promedio de O(log n) paso por
operacin, par un conjunto de tamao n.
Ejemplo
16

20

9
1

19
11

17

10
23

21

3
1

29
15

22

32
24

35
34

Qu ocurre si los nodos de un rbol binario de bsqueda se listan en Inorden?

Material preparado por PEDRO ROSSEL CID

37

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 58

Operaciones sobre Arboles Binarios de Bsqueda


FUNCTION PERTENENCIA(X:tipo_dato; A: struct tipo_nodo *):BOOLEAN {
IF A= =NULL
RETURN(FALSE)
ELSE
IF X = A->info
RETURN(TRUE)
ELSE
IF X < A->info
RETURN(PERTENENCIA(X, A->hijo_izq))
ELSE
RETURN(PERTENENCIA(X, A->hijo_der))
}
PROCEDURE INSERCION(X:tipo_dato; A: struct tipo_nodo *) {
IF A= =NULL {
malloc(A);
A->info = X;
A->hijo_izq = NULL;
A->hijo_der = NULL
}
ELSE
IF X < A->info
INSERCION(X, A->hijo_izq)
ELSE
INSERCION(X, A->hijo_der)
}
Eliminacin
La eliminacin presenta algunos inconvenientes:
Se debe localizar el elemento X que se desea eliminar del rbol. Si X est en una hoja,
tal vez baste eliminar dicha hoja.
Si X est en un nodo interior, la eliminacin de ste puede desconectar el rbol.
Si el nodo a eliminar tiene un nico descendiente, entonces se sustituye por ese
descendiente.
Si el nodo a eliminar tiene dos descendientes, entonces se tiene que sustituir por el
nodo que se encuentra ms a la izquierda en el subrbol derecho (o por el nodo que se
encuentra ms a la derecha del subrbol izquierdo).
Ejemplo
Al eliminar el elemento 10 del rbol, ste queda como el rbol de la derecha.
10
Material preparado por PEDRO ROSSEL CID

12

Algoritmos y Estructuras de Datos, Apuntes de Clases

14
7

12

Pgina 59

5
18

14
7

15

18
15

Anlisis del Algoritmo


Para la pertenencia, la longitud del camino promedio de la raz a la hoja, para insertar
n elementos aleatorios en un rbol binario de bsqueda inicialmente vaco, es O(logn).
Si un rbol binario de n nodos est completo, es decir, todos los nodos, excepto las
hojas, tienen 2 hijos, ningn camino tendr ms de 1 + logn nodos. As los procedimientos
pertenencia, insercin, eliminacin y elimina mnimo son de orden O(logn).

3.4.3 Arboles Balanceados


Los rboles balanceados surgen con la finalidad de mejorar la bsqueda en los
rboles binarios de bsqueda. Por ejemplo:
40
30
Material preparado por PEDRO ROSSEL CID

50

Algoritmos y Estructuras de Datos, Apuntes de Clases

20

35

Pgina 60

45

55

25
23

28
24

Este rbol es binario de bsqueda, pero al realizar la bsqueda de alguno de sus


elementos, el tiempo es muy dismil. Si se busca el 24, se deben realizar 6 consultas al rbol
para determinar que s est. Si se busca el 45 se realizan 3 consultas. Luego lo que se desea
es que la cantidad de consultas sea en el pero de los casos igual o difiera a lo ms en 1.
Para tener rboles balanceados, se realizan acomodos o balanceos despus de cada
insercin o eliminacin de elementos.
Los inventores de estos rboles son dos matemticos rusos:
G.M. Adelson-Velskii y E.M. Landis
por lo que estos rboles tambin son llamados AVL.
Definicin
Un rbol balanceado es un rbol binario de bsqueda, en el que para todo nodo T del
rbol, la altura de los subrboles izquierdo y derecho no debe diferir en ms de una
unidad.
Ejemplos
a)

20

b)

10
5

30
15

AVL

25

60
40

35

80
45

70

88
82

c)

d)
2

89

10

No AVL

20

19
4

18

Note que el insertar elementos en un rbol balanceado puede provocar que ste se
desbalancee. Lo mismo sucede al eliminar elementos de un rbol balanceado.
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 61

Por ejemplo, si se insertan los elementos 3, 2, 1, en ese orden, al rbol a) ste queda
desbalanceado.
20
10
5

30
15

25

35

3
2
1
En cambio si se insertan los elementos 30, 8, 7, 9 en rbol d), ste queda balanceado.
10
8
7

20
9

19

30

18
Los rboles balanceados se parecen, en su mecanismo de formacin, a los nmeros
de Fibonacci. Un rbol de altura cero es vaco; el rbol de altura uno tiene un solo nodo; la
frmula para un rbol de altura h > 1 es:
kh = kh-1 + 1 + kh-2
donde k representa el nmero de nodos mnimo de rbol y h representa la altura del mismo.
Nota:

k0 = 0

k1 = 1

Ejemplo
h=3

k3 = k2 + 1 + k1 = (k1 + 1 + k0) + 1 + k1
k3 = 1 +1 + 0 + 1 + 1
k3 = 4

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

h=2

k2 = k1 + 1 + k0 = 1 + 1 + 0
k2 = 2

h=4

k4 = k3 +1 + k2 = (k2 + 1 + k1) + 1 + (k1 + 1 + k0)


k4 = (k1 + 1 + k0) + 1 + k1 + 1 + k1 + 1 + k0
k4 = 1 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 0
k4 = 7

Pgina 62

Insercin en Arboles Balanceados


Se deben distinguir los siguientes casos:
1.- Las ramas izquierda (RI) y derecha (RD) del rbol tiene igual altura (HRI = HRD). As:
a) Si se inserta un elemento en RI, HRI > HRD
b) Si se inserta un elemento en RD, H RD > HRI
2.- Las ramas izquierda (RI) y derecha (RD) del rbol tiene distinta altura (HRI HRD). As:
Supngase que HRI < HRD
a)
Si se inserta un elemento en RI, HRI = HRD
i.
ii. Si se inserta un elemento en RD, se rompe el balance y es necesario
reestructurar.
b) Supngase que HRI > HRD
i. Si se inserta un elemento en RI, se rompe el balance y es necesario
reestructurar.
Si
se inserta un elemento en RD, HRI = HRD
ii.
Para poder determinar si un rbol est balanceado o no se maneja el concepto de
Factor de Equilibrio (FE), que se define como la altura del subrbol derecho menos la
altura del subrbol izquierdo. Los valores que FE puede tomar, para que el rbol est
balanceado son: -1, 0, 1. Si FE toma los valores de -2 o 2 se debe reestructurar el rbol.
Ejemplo

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 63

-1
40

30

60

1
25

35

70

0
37

Figura 19
El rbol de la figura 31 tiene sobre cada nodo el valor FE para dicho nodo.
El FE para el nodo 30 se calcula:
FE30 = 2 - 1 = 1
Para el nodo 60
FE60 = 1 - 0 = 1
Para representar los AVL en C podemos tener una definicin de tipos como la
siguiente:
enum valores {menosuno=-1, cero=0, uno=1};
struct nodo{
tipo_elemento info;
enum valores FE;
struct nodo *izq, *der;
};
Reestructuracin del Arbol Balanceado
Si en alguno de los nodos se viola el criterio de equilibrio, es decir, FE = 2 o FE =-2,
el rbol debe ser reestructurado.
Reestructurar significa rotar los nodos del rbol. La rotacin puede ser simple o
compuesta. Si la rotacin es simple puede realizarse por las ramas derechas (DD) o por las
ramas izquierdas (II). Si es compuesta puede realizarse por las ramas derecha e izquierda
(DI) o por las ramas izquierda y derecha (ID).
En las siguientes figuras se vern los distintos tipos de rotacin.
Rotacin II: La insercin de 10 desbalancea el rbol

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 64

-2
N O D O

30

-1

20

0
20

N O D O 1

10

0
10

N O D O - > IZ Q
= N O D O 1 -> D E R
N O D O 1 -> D E R = N O D O
N O D O
= N O D O 1

30

Figura 20
Rotacin DD: La insercin de 30 desbalancea el rbol
2

N O D O

10

20

N O D O 1

N O D O - > D E R = N O D O 1 - > IZ Q
N O D O 1 - > IZ Q = N O D O
N O D O
= N O D O 1

20

0
10

30

30

Figura 21

Rotacin DI: La insercin de 20 desbalancea el rbol


2

N O D O

10

30

20

-1
N O D O 1

0
10

20

N O D O 12

Figura 22

Material preparado por PEDRO ROSSEL CID

30

N
N
N
N
N

O
O
O
O
O

D
D
D
D
D

O
O
O
O
O

1 - > IZ Q
2 -> D E R
-> D E R
2 - > IZ Q

=
=
=
=
=

N O D O 2 -> D E R
N O D O 1
N O D O 2 - > IZ Q
N O D O
N O D O 2

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 65

Rotacin ID: La insercin de 20 desbalancea el rbol


-2
N O D O

30

N
N
N
N
N

20
10

N O D O 1

0
10

20

30

O
O
O
O
O

D
D
D
D
D

O
O
O
O
O

1 -> D E R
2 -> IZ Q
- > IZ Q
2 -> D E R

=
=
=
=
=

N O D O 2 - > IZ Q
N O D O 1
N O D O 2 -> D E R
N O D O
N O D O 2

N O D O 2

Figura 23
Ejemplo
Se desea ingresar las siguientes claves en un rbol vaco:
65
0

50

23

82

68

39

-2

-1

65

70

65

65

-1

R o ta c i n II

50

50

0
23

0
50

0
23

65

50

50

1
23

2
23

65

R o ta c i n D D

65

0
70

70

0
82

Figura 24
El resto de las inserciones pueden ser revisadas en el libro Estructura de Datos de
Cair/Guardati.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 66

Eliminacin en Arboles Balanceados


La eliminacin consiste en quitar un nodo del rbol sin que se violen los principios
que definen a un rbol balanceado.
La eliminacin en rboles balanceados ocupa el mismo algoritmo que para un rbol
binario de bsqueda, y las mismas operaciones de reacomodo utilizadas para inserciones en
estos rboles, si se produce un desbalanceo al eliminar un nodo.
Ejemplo
Elimine las claves 82 10 39 65 70 23 y 50 del siguiente rbol.

Figura 25
Eliminar 82
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Figura 26

Eliminar 10

Figura 27
Eliminar 39

Material preparado por PEDRO ROSSEL CID

Pgina 67

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 68

Figura 28
Eliminar 65

Figura 29
Eliminar 70, 23 y 50

Figura 30

Ejercicio
Para el rbol de la Figura 31, elimine las claves 25 75 66 65 62 10 43 y
47.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Figura 31

El resultado podra resultar el rbol de la Figura 32.

Figura 32
3.4.4 Arboles B-Trees

Material preparado por PEDRO ROSSEL CID

Pgina 69

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 70

Los rboles B-Trees son una generalizacin de los rboles balanceados. Estos
rboles representan un mtodo de bsqueda utilizando rboles multicaminos. Fueron
propuestos por Bayer y McCreight en 1970.
1. En general cada nodo de un B-Tree de orden d contiene 2d claves como mximo y d
como mnimo, excepto la raz, que puede tener como mnimo 1. Tambin se suele llamar
a cada nodo pgina.
2. Cada nodo, excepto la raz y las hojas, tiene entre d+1 y 2d+1 descendientes. Se utilizar
m para expresar el nmero de elementos por nodo.
3. La raz tiene al menos dos descendientes.
4. Las hojas estn al mismo nivel.
Ejemplos
36

15

40

20

38

44

Figura 33: B-Tree de orden 1


40

25

30

66

45

60

70

75

80

90

Figura 34: B-Tree de orden 2


Ahora, la pregunta que se puede formular es cul es el orden que se debe elegir para
un determinado problema. Lamentablemente esto no es muy fcil de responder. Una idea
que puede dar alguna luz al respecto es la siguiente:
Es sabido que en muchas aplicaciones se hace necesario almacenar la
informacin en disco (almacenamiento secundario). Este acceso es lento.
Supngase que se almacena un rbol binario. Al recuperar la informacin
se necesitarn log2n accesos a disco, en promedio, para localizar algn
nodo. Si el rbol contiene 1.000.000 de elementos se necesitarn
aproximadamente 20 accesos a disco. Si el rbol es un B-Tree, por
ejemplo de orden 100, se necesitarn como mximo 3 accesos a disco
(log1001.000.000). De esta forma el acceso a disco ha disminuido.
Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 71

3.4.4.1 Bsqueda
La bsqueda es anloga a la realizada sobre un rbol binario de bsqueda. Lo ms
seguro es que se deba recorrer secuencialmente cada nodo, en busca del elemento, o de los
hijos que puedan contener el elemento.
Ejemplo
Buscar el elemento 70 y el 90.
20

10

50

35

45

60

65

68

70

Figura 35
3.4.4.2 Insercin en rboles B-Tree
Los B-Trees crecen en el sentido contrario de los rboles normales, es decir, crecen
desde las hojas hacia la raz.
Si se desea insertar una clave, se debe ubicar primero el nodo que le corresponde. Si
el nmero de elementos es menor a 2d, simplemente se inserta. Si es igual a 2d, entonces las
2d+1 claves se distribuyen en dos grupos equitativos. La clave del medio sube al nodo
antecesor (padre)
Ejemplo
Insertar las siguientes claves, para un rbol B de orden 2:
5
35

10
4

30
40

21
60

14

44

Desarrollo
Insertar 5, 10, 30, 21

Figura 36

Material preparado por PEDRO ROSSEL CID

32

25

90

85

88

Algoritmos y Estructuras de Datos, Apuntes de Clases

Insertar 1

Figura 37

Insertar 14, 44

Figura 38
Insertar 32

Figura 39
Insertar 25, 90, 85

Material preparado por PEDRO ROSSEL CID

Pgina 72

Algoritmos y Estructuras de Datos, Apuntes de Clases

Figura 40
Insertar 88

Figura 41

Insertar 2, 35, 4, 40

Figura 42
Insertar 60

Figura 43
Ejercicio
Material preparado por PEDRO ROSSEL CID

Pgina 73

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 74

Dado un rbol B de orden 2 de la Figura 44, inserte las siguientes claves:


43 21 77 58 63 15 37 41 72 39 95 70

Figura 44

3.4.4.3 Eliminacin en rboles B-Tree


Esta consiste en quitar una clave del rbol sin violar los principios que definen a un
rbol B. Se deben distinguir los siguientes casos (m es el nmero de elementos de un
pgina):
1. Si la clave a borrar se encuentra en una pgina hoja, entonces simplemente se
suprime.
a. Si m >= d entonces
Termina la operacin de borrado
Sino
Debe bajarse la clave lexicogrficamente adyacente de la pgina antecedente
y sustituir esta clave por la que se encuentra ms a la derecha en el subrbol
izquierdo o por la que se encuentra ms a la izquierda en el subrbol derecho.
Es decir, que m en esta pgina siga siendo >= d, de otra forma fusionar las
pginas que son descendientes directas de dicha clave.
2. Si la clave a borrar no se encuentra en una pgina hoja, entonces se debe sustituir
por la clave que se encuentra ms a la izquierda en el subrbol derecho o por la clave
que se encuentra ms a la derecha en el subrbol izquierdo.
a. Si m >= d entonces
Termina la operacin de borrado
Sino
Debe bajarse la clave lexicogrficamente adyacente de la pgina antecedente
y fusionar las pginas que son descendientes directas de dicha clave.
Se debe aclarar que el proceso de fusin puede propagarse incluso hasta la raz, en
cuyo caso la altura del rbol disminuye en una unidad.
Ejemplos

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Eliminar 27

Figura 45

Eliminar 21

Figura 46
Eliminar 10

Figura 47
Eliminar 15

Material preparado por PEDRO ROSSEL CID

Pgina 75

Algoritmos y Estructuras de Datos, Apuntes de Clases

Figura 48

Eliminar 25

Figura 49
Eliminar 21

Material preparado por PEDRO ROSSEL CID

Pgina 76

Algoritmos y Estructuras de Datos, Apuntes de Clases

Figura 50

Eliminar 25

Material preparado por PEDRO ROSSEL CID

Pgina 77

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 78

Figura 51
Ejercicio
Eliminar las claves 25 24 29 27 48 19 51 21 13 15 17 66 y 10 del rbol
de la Figura 52.

Figura 52

3.5

Grafos

3.5.1 Introduccin a la Teora de Grafos


Definicin
Un par de conjuntos G=(V, E) es un grafo dirigido (digrafo), si EVV. Los
elementos de V se llaman vrtices y los elementos de E se llaman arcos.
Si existe un arco desde x a y decimos que x es adyacente a y.
El nmero de arcos incidentes desde un vrtice se llama out-degree del vrtice, y el
nmero de arcos incidentes hacia un vrtice se llama in-degree del vrtice.
Un arco desde un vrtice a s mismo se llama loop.
Un digrafo que no contiene loops se llama loop-free.
Ejemplo:
V = {v1, v2, v3, v4, v5}
E = {a1, a2, a3, a4, a5, a6} = {(v1, v2), (v2, v3), (v2, v1), (v1, v3), (v1, v4), (v4, v4)}

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 79

v2
a1

a2
a3

v1

v3
a4

a5
v4

a6

Figura 53
Definicin
Un grafo G es un par de conjuntos (V, E), donde V es un conjunto de vrtices y E es
un conjunto de arcos (aristas). Si G es un grafo dirigido, los elementos de E son pares
ordenados de vrtices. En este caso se dice que un arco (u, v) va desde u hasta v, y que
conecta u a v.
Si G es un grafo no dirigido, los elementos de G son pares no ordenados de vrtices.
En este caso una arista (u, v) conecta u y v o est entre u y v. Un arco (arista) entre un
vrtice y el mismo se llama loop. Un grafo sin loops se llama simple.
Si G es finito, /V(G)/ denota el nmero de vrtices en G y se llama orden de G. De
manera similar, con G finito, /E(G)/ denota el nmero de arcos en G, y es llamado tamao
de G.
El grado de un vrtice en un grafo simple es el nmero de arcos incidentes. Si no es
simple, cada loop se cuenta dos veces.
Un vrtice de grado cero se llama vrtice aislado.
b

G'

Figura 54
El grafo G no es simple, ya que existe un loop en el vrtice c. El grafo G s es
simple, pues no contiene loops.
GradoG(c) = 5

Material preparado por PEDRO ROSSEL CID

GradoG(c) = 3

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 80

Obsrvese que los grafos no dirigidos pueden ser vistos como grafos simtricos
dirigidos, en los cuales para cada arco (u, v) entre dos vrtices, hay tambin un arco entre
los mismos vrtices en la otra direccin.
Teorema (Primer Teorema de la Teora de Grafos)
Si V = {v1, v2, ..., vn} es un conjunto de vrtices de un grafo no dirigido G,
entonces
n

Grado(vi) = 2*/E/
i=1
Si G es un grafo dirigido, entonces
n

Grado (vi) = Grado-(vi) = /E/


+

i=1
(in-degree)

i=1
(out-degree)

Corolario
En cualquier grafo no dirigido hay un nmero par de vrtices de grado impar.
Ejemplo
Cuntos vrtices tendr un grafo si contiene 21 aristas y todos los vrtices de grado
2?
/E/ = 21
Por el teorema se sabe que
n

Grado(vi) = 2*/E/ = 2*21 = 42


i=1
Luego
n

Grado(vi) = 2*N de vrtices


i=1
N de vrtices = 42/2 = 21

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 81

3.5.2 Clases Especiales de Grafos


Gran parte del trabajo en teora de grafos se ha relacionado con unas pocas clases
bien definidas de grafos. Las clases ms estudiadas incluyen grafos regulares, completos,
bipartitos y rboles.
Un grafo G es regular de grado k, o k-regular, si cada uno de sus vrtices tiene
grado k. O sea, un grafo regular es uno con el mismo nmero de aristas incidentes en cada
vrtice.
Un grafo 3-regular, llamado grafo cbico, constituye el primer conjunto no trivial de
grafos regulares.
Algunos de ellos estn mostrados en la Figura 55.

Figura 55
Un grafo G de n vrtices es completo si cada posible vrtice (vi, vj), vi vj es una
arista.
El grafo completo de n vrtices es denotado por kn (ntese que kn es regular de
grado n-1).

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 82

k5

k6

Figura 56
Si H es un subgrafo de un grafo (conexo) G, el complemento de H con respecto a
G, G H, consiste de todas las aristas de G que no estn en H, y los vrtices asociados a
estas aristas. En particular, el complemento de H, H, es el complemento de H con respecto a
kn, donde H tiene n vrtices.

G:

x3

G-H:

H:

x3

x3

x2

x2

x2

x4

x4

x1

x1

x1

x5

x5

Figura 57
G:

G-H:

H:
x2

x3

x3

x2

x1

x4

x4

x1

Figura 58
Complemento de H
Si:
Material preparado por PEDRO ROSSEL CID

x3

Algoritmos y Estructuras de Datos, Apuntes de Clases

H:

Pgina 83

H:
n=3

H:

H:
n=4

H:

H:

n=5

Figura 59
Un grafo es bipartito si sus vrtices pueden agruparse en dos conjuntos disjuntos, V
y W, de tal forma que ningn vrtice en V (en W) est conectado a otro en V (en W) por una
arista. G es un grafo bipartito completo, si adems cada vrtice en V est conectado a cada
vrtice en W. Los grafos con loop no son bipartitos.
Ejemplo:
x2

x3

x1

x4
x5

Figura 60
La figura 60 muestra un grafo bipartito, con los siguientes conjuntos V y W:
V = {x1, x3}
W = {x2, x4, x5}

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases


x2

Pgina 84
x3

x1

x4

Figura 61
La Figura 61 muestra un grafo que no es bipartito
Tambin se llaman bicoloreables. Esta resulta una buena tcnica para separar ambos
conjuntos.
Si V consiste de m vrtices y W consiste de n vrtices, el grafo bipartito completo
sobre los vrtices V W se denota por km,n. Para estandarizar suponemos m n.
Ntese que km,n es conexo.
La Figura 62 muestra algunos grafos bipartitos completos.
k1,1

k1,2

k2,4

k3,5

k2,2

Figura 62
Un rbol es un grafo conexo, finito, no dirigido, que no contiene ciclos.
Definicin: Un grafo finito es un rbol si y slo si:

Es conexo y acclico o
Es conexo con n vrtices y n 1 aristas
Es acclico, pero la adicin de una arista forma un ciclo.

Para cualquier grafo finito conexo, es posible encontrar un rbol que contiene todos
los vrtices del grafo. Tal rbol es llamado rbol de cobertura del grafo.

Material preparado por PEDRO ROSSEL CID

Algoritmos y Estructuras de Datos, Apuntes de Clases

Pgina 85

Grafo

rboles de Cobertura
Figura 63

Un circuito es la trayectoria a1, a2, ..., aq en la cual el vrtice inicial de a1 coincide


con el vrtice final.
Un ciclo es la contraparte no dirigida de un circuito. As un ciclo es una cadena x1,
x2, ..., xq en la cual el vrtice inicial y final son el mismo.
Un grafo se dice fuertemente conexo, si para 2 vrtices distintos cualesquiera xi, xj,
hay al menos una trayectoria que va desde xi a xj. Esto significa que 2 vrtices cualesquiera
de un grafo fuertemente conexo son mutuamente alcanzables.

3.5.3 Representacin matricial


3.5.3.1 Matriz de Adyacencia
Dado un grafo G, su matriz de adyacencia es denotada por A=[aij] y est dada por:
aij = 1 Si existe el arco (xi, xj) en G
aij = 0 Si el arco (xi, xj) no existe en G
Ejemplo:
Dado el grafo de la Figura 64 escriba su matriz de adyacencia.

x1

a1

x2

a3

a9
x6

a2

a8

a10

x3

a4
a5

a7
x5

a6

Figura 64

Material preparado por PEDRO ROSSEL CID

x4

Algoritmos y Estructuras de Datos, Apuntes de Clases

x1
x2
x3
x4
x5
x6

A=

x1
0
0
0
0
1
1

x2
1
1
0
0
0
0

x3
1
0
0
1
0
0

Pgina 86

x4
0
0
0
0
1
0

x5
0
1
0
0
0
1

x6
0
0
0
0
0
1

Outdegree

Indegree

3.5.3.2 Matriz de Incidencia


Dado un grafo G de n vrtices y m arcos, la matriz de incidencia de G es denotada
por B[bij], y es una matriz de n m definida de la siguiente forma:
bij = 1 si xi es el vrtice inicial del arco aj
bij = 1 si xi es el vrtice final del arco aj
bij = 0 si xi no es un vrtice terminal del arco aj, o si aj es un loop
La matriz de incidencia del grafo de la Figura 64 es la siguiente:

B=

x1
x2
x3
x4
x5
x6

a1
1
1
0
0
0
0

a2
1
0
1
0
0
0

a3
0
0
0
0
0
0

Material preparado por PEDRO ROSSEL CID

a4
0
1
0
0
1
0

a5
0
0
1
1
0
0

a6
0
0
0
1
1
0

a7
0
0
0
0
1
1

a8
1
0
0
0
1
0

a9
1
0
0
0
0
1

a10
0
0
0
0
0
0