Você está na página 1de 62

Estructuras de datos en memoria principal

Franco Guidi Polanco


Escuela de Ingeniera Industrial
Pontificia Universidad Catlica de Valparaso, Chile
fguidi@ucv.cl

Estructuras de datos
vEstructuras bsicas
Arreglo
Lista enlazada
Simplemente enlazada
Doblemente enlazada

vColecciones implementadas sobre las estructuras bsicas:

Lista, Lista con iterador


Lista circular
Pila
Cola
Hashtable
Vector (Java)
(Otras)

Franco Guidi Polanco (PUCV-EII)

25-05-14

Arreglo
vEs una coleccin ordenada de elementos del
mismo tipo.
vEs de largo fijo, definido al momento de
instanciarlo.
vEl acceso a los elementos se hace a travs de un
subndice.
vFcil de recorrer en ambos sentidos.
vEstudiado en cursos anteriores

Franco Guidi Polanco (PUCV-EII)

25-05-14

Listas enlazadas
vSon estructuras dinmicas: se asigna memoria
para los elementos de la lista en la medida que es
necesario.
vCada elemento se almacena en una variable
dinmica denominada nodo.
vEn la lista simplemente enlazada, cada nodo
apunta al nodo que contiene el elemento siguiente

Franco Guidi Polanco (PUCV-EII)

25-05-14

Esquema tentativo de una lista simplemente


enlazada

Nodos

data

data

head

data

null

ListaEnlazada

Franco Guidi Polanco (PUCV-EII)

data

25-05-14

Datos contenidos en la lista


vLos nodos de una lista contendrn datos del tipo
declarado en la estructura del nodo. Por ejemplo:
Tipos primitivos (byte, int, boolean, char, etc.)
Referencias a objetos

vEn los siguientes ejemplos consideraremos el uso


de listas de enteros, aunque las tcnicas que sern
descritas son aplicables a cualquier otro tipo de
lista.

Franco Guidi Polanco (PUCV-EII)

25-05-14

Diagrama de clases de una lista simplemente


enlazada
vDiagrama de clases (lista de enteros):
next
Lista

1..1
head

agregarAlFinal(d:Data)
estContenido(d:Data):boolean
eliminar(d:Data):boolean
imprimirContenido()

Nodo
data:int
getData():int
setNext(n:Nodo)
getNext():Nodo
Nodo(d:Data,n:Nodo)

vDiagrama de objetos:
:Lista

head:Nodo
data = 1

Franco Guidi Polanco (PUCV-EII)

25-05-14

:Nodo

:Nodo

data = 20

data = -1

Una lista simplemente enlazada (versin


preliminar)
vDeclaracin de la Lista:
public class Lista{
Nodo head = null;
public void agregarAlFinal(int data){
...
}
public void imprimirContenido(){
...
}
public boolean estaContenido(int data){
...
}
public boolean eliminar(int data){
...
}
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

Nodos en una lista simplemente enlazada


public class Nodo{
private int data;
private Nodo next;
public Nodo(int d, Nodo n){
data = d;
next = n;
}
public int getData(){
return data;
}
public Nodo getNext(){
return next;
}
public void setNext(Nodo n){
next = n;
}
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

Insercin en la lista simplemente enlazada

vInsertar elementos:

Ejemplo: [ 25, 1, 14, 4 ]

Al final de la lista
25

14

head

null

Manteniendo un orden
1

14

25

head

null

Al inicio de la lista
4

14

head
Franco Guidi Polanco (PUCV-EII)

25

null
25-05-14

10

Insercin de elementos al final de la lista


vCaso 1: la lista est vaca (variable head contiene
null)
25

head

head

null

null

public Lista{
...
public void agregarAlFinal(int dato){
...
head = new Nodo( dato, null );
...
}
...
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

11

Insercin de elementos al final de la lista


vCaso 2 (general): la lista tiene al menos un
elemento
25

1. ubicar ltimo nodo de la lista


(aqul cuya variable next
contiene null)
2. Instanciar el nuevo nodo
con el contenido indicado
3. Asignar el nuevo nodo a la
variable next del ltimo
nodo (asegurndose de que
la variable next del nuevo
nodo sea igual a null)

head

null
aux

25

14

head

null
aux

Franco Guidi Polanco (PUCV-EII)

aux.setNext(new Nodo(dato, null));


25-05-14

12

Insercin de elementos al final de la lista


vCaso general:
public class Lista{
...
public void agregarAlFinal(int dato){
Nodo nuevo = new Nodo(dato, null);
if( head == null )
head = nuevo;
else{
Nodo aux = head;
while( aux.getNext() != null)
aux = aux.getNext();
aux.setNext( nuevo );
}
}

...
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

13

Recorrido de la lista
vMtodo que imprime el contenido de la lista:
public class Lista{
...
public void imprimirContenido(){
Nodo aux = head;
while( aux != null ){
System.out.print( aux.getData() + "; " );
aux = aux.getNext();
}
System.out.println();
...

Franco Guidi Polanco (PUCV-EII)

25-05-14

14

Bsqueda en la lista
vRetorna true si el elemento est contenido en la
lista
public class Lista{
...
public boolean estaContenido(int data){
Nodo aux = head;
while( aux != null ){
if( data == aux.getData() )
return true;
aux = aux.getNext();
}
return false;
}

...
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

15

Eliminacin de un elemento
vRequiere identificar el nodo a borrar.
vCaso 1: es el primer nodo de la lista

25

14

head

null

head = head.getNext();
25

head

Sin otras referencias: candidato a eliminacin


(recolector de basura de Java)
1

14

head
Franco Guidi Polanco (PUCV-EII)

14

null

null
25-05-14

16

Eliminacin de un elemento
vCaso 2 (general): no es el primer nodo de la lista

25

14

head

null
aux.setNext(aux.getNext().getNext());

aux
25

head

Sin otras referencias: candidato a eliminacin


(recolector de basura de Java)
25

head
Franco Guidi Polanco (PUCV-EII)

14

null

null
25-05-14

17

Eliminacin de un elemento
public class Lista{
...
public boolean eliminar(int data){
if( head != null)
if( head.getData() == data ){
head = head.getNext();
return true;
}else{
Nodo aux = head;
while( aux.getNext() != null ){
if( aux.getNext().getData() == data ){
aux.setNext( aux.getNext().getNext() );
return true;
}
aux = aux.getNext();
}
}
return false;
}
...
}
Franco Guidi Polanco (PUCV-EII)

25-05-14

18

Simplificacin del esquema propuesto: uso de un


nodo fantasma
vEn el esquema propuesto se deben hacer
excepciones al insertar y eliminar el nodo del
comienzo de la lista.
vEl manejo se simplifica si se utiliza un nodo
fantasma:
Es un nodo siempre presente en la lista
Su contenido es irrelevante (el valor u
objeto contenido no forma parte de la lista).

Franco Guidi Polanco (PUCV-EII)

25-05-14

19

Lista simplemente enlazada con nodo fantasma

vLista vaca:

head

public class Lista{


Nodo head;
public Lista(){
head = new Nodo(0, null);
}

...

null

vLista con elementos:

Valor irrelevante
25

head

null
Primer elemento de la lista

Franco Guidi Polanco (PUCV-EII)

25-05-14

20

Operacin de insercin en la lista con nodo fantasma

vLa insercin del primer elemento de la lista entra


en el caso general:
1

head

null

aux

Clase
Lista

aux.setNext(new Nodo(dato, null));

public void agregarAlFinal(int dato){


Nodo aux = head;
while( aux.getNext() != null)
aux = aux.getNext();
aux.setNext( new Nodo(dato, null) );
}
}

Franco Guidi Polanco (PUCV-EII)

25-05-14

21

Eliminacin del primer elemento en la lista con nodo


fantasma

vLa eliminacin del primer elemento de la lista entra


en el caso general:

aux

aux.setNext(aux.getNext().getNext());

14

head

null
Sin otras referencias: candidato a eliminacin
(recolector de basura de Java)

Franco Guidi Polanco (PUCV-EII)

25-05-14

22

Eliminacin del primer elemento en la lista con nodo


fantasma (cont.)

public boolean eliminar(int data){


Nodo aux = head;
while( aux.getNext() != null ){
if( aux.getNext().getData() == data ){
aux.setNext( aux.getNext().getNext() );
return true;
}
aux = aux.getNext();
}
return false;
}

Franco Guidi Polanco (PUCV-EII)

25-05-14

23

Mejora al procedimiento de insercin de elementos al final


de la lista
vEl procedimiento descrito anteriormente requiere que todas
las veces sea encontrado el ltimo elemento de la lista.
vMs conveniente: tener una variable de instancia que
siempre referencie al ltimo elemento de la lista.
vEsto aplica a listas con o sin nodo fantasma (con pequeos
cambios).

Franco Guidi Polanco (PUCV-EII)

25-05-14

24

Mejora al procedimiento de insercin de


elementos al final de la lista (cont.)
vDiagrama de clases:
Lista

1..1

agregarAlFinal(d:Data)
estContenido(d:Data)
eliminar(d:Data):boolean
imprimirContenido()

head
1..1

1..1
tail

Nodo
data: int
getData():Data
setNext(n:Nodo)
getNext():Nodo
Nodo(d:Data,n:Nodo)

vDiagrama de objetos:
Lista

head

ghost:Nodo

1stNode:Nodo

2ndNode:Nodo

data = 20

data = -1
tail

Franco Guidi Polanco (PUCV-EII)

25-05-14

25

Mejora al procedimiento de insercin de elementos al final


de la lista (cont.)
vLa variable de instancia tail mantiene siempre la
referencia al ltimo elemento:

head

null

public class Lista{


Nodo head, tail;
public Lista(){
head = new Nodo(0, null);
tail = head;
}

tail

...
}
25

head

null

tail
Franco Guidi Polanco (PUCV-EII)

25-05-14

26

Mejora al procedimiento de insercin de elementos al final


de la lista (cont.)
vEl mtodo agregarAlFinal ya no requiere recorrer la
lista para ubicar el ltimo nodo:
public void agregarAlFinal(int dato){
Nodo aux = new Nodo(dato, null) ;
tail.setNext( aux );
tail = aux;

Versin con
nodo fantasma

vLa varaible tail es actualizada despus de la insercin.


vNotar que el procedimiento de eliminacin debe actualizar
la referencia tail si se remueve el ltimo nodo de la lista.

Franco Guidi Polanco (PUCV-EII)

25-05-14

27

Insercin en orden/al inicio


vEjercicio 1: implemente el mtodo:
agregarEnOrden(int dato)
que recibe un entero y lo agrega en orden
ascendente a la lista.
vEjercicio 2: implemente el mtodo
agregarAlInicio(int dato)
que recibe un entero y lo agrega como
primer elemento.

Franco Guidi Polanco (PUCV-EII)

25-05-14

28

Resumen listas simplemente enlazadas


vtiles para guardar un nmero no predefinido de
elementos.
vDistintas disciplinas para mantener los datos
ordenados (y para removerlos).
vEl acceso a los nodos es secuencial; el recorrido es
en una sola direccin (Ejercicio: confrontar con
arreglos)

Franco Guidi Polanco (PUCV-EII)

25-05-14

29

Listas doblemente enlazadas


vEstn diseadas para un acceso fcil al nodo siguiente y al
anterior.
vCada nodo contiene dos referencias: una apuntando al nodo
siguiente, y otra apuntando al nodo anterior.
vEl acceso a los nodos sigue siendo secuencial.
vLa tcnica del nodo fantasma puede ser til tambin en este
tipo de lista.

14

head

null
null

Franco Guidi Polanco (PUCV-EII)

25-05-14

30

Comentarios finales sobre estructuras elementales


vEstar abierto a definir y utilizar otras estructuras.
vEjemplo: Lista simplemente enlazada y circular

25

14

head

Franco Guidi Polanco (PUCV-EII)

25-05-14

31

Colecciones implementadas sobre estructuras


bsicas
Franco Guidi Polanco
Escuela de Ingeniera Industrial
Pontificia Universidad Catlica de Valparaso, Chile
fguidi@ucv.cl

Interfaces versus implementacin


vEn la seccin anterior estudiamos estructuras elementales
para implementar colecciones.
vEn esta seccin estudiaremos colecciones clsicas, desde
dos perspectivas:
La interfaz de la coleccin (cmo se utiliza)
La implementacin de la coleccin (cmo se construye)

vUna misma interfaz puede ser soportada por mltiples


implementaciones
vLa eficiencia en la operacin de una coleccin va a
depender de su implementacin

Franco Guidi Polanco (PUCV-EII)

25-05-14

33

Listas
v Representa una coleccin conformada por una secuencia finita y
ordenada de datos denominados elementos.
v Ordenada implica que cada elemento tiene una posicin.
v Los elementos corresponden a un tipo de dato.
v La lista est vaca cuando no contiene elementos.
v El nmero de elementos se denomina largo de la lista.
v El comienzo de la lista es llamado cabeza (head), y el final cola
(tail).
v Notacin: (a1, a2, ..., an).

Franco Guidi Polanco (PUCV-EII)

25-05-14

34

Lista: versin clsica


vAdems de los datos, el estado de la lista contiene
una identificacin (referencia) al dato actual.
(12, 22, 50, 30).

vLa lista provee operaciones para:

Cambiar (modificar la referencia) del dato actual


Retornar el dato actual
Eliminar el dato actual
Modificar el dato actual
Insertar un dato en la posicin del dato actual
Borrar toda la lista, buscar elementos en la lista, contar
sus elementos

Franco Guidi Polanco (PUCV-EII)

25-05-14

35

Interfaces para la versin clsica de la lista


vNo hay una nica definicin formal de interfaz.
vEstudiaremos dos extremos:
Interfaz elemental
Interfaz extendida

Franco Guidi Polanco (PUCV-EII)

25-05-14

36

Interfaz elemental para la lista clsica


public interface List {
public void clear();
//
public void insert(Object item); //
public Object remove();
//
public void setFirst();
//
public void next();
//
public int length();
//
public void setValue(Object val);//
public Object currValue();
//
public boolean isEmpty();
//
public boolean eol();
//
public String toString();
//
}

Elimina todos los elem.


Inserta elem. en act.
Saca/retorna elem.
Setea act. en 1ra pos.
Mueve act. a sig. pos.
Retorna largo
Setea elemento
Retorna elemento
True: lista vaca
True: act en end of list
Retorna lista de elem.

Nota: pos.=posicin; act.=posicin actual; sig.:siguiente; prev.:previa


Franco Guidi Polanco (PUCV-EII)

25-05-14

37

Ejemplo de uso de una lista (versin clsica)


vSea la siguiente lista:

vOperaciones:

miLista=(12, 22, 50, 30)


Dato actual

miLista.insert(99) :
miLista=(12, 99, 22, 50, 30)
miLista.next():
Dato actual

miLista=(12, 99, 22, 50, 30)


Dato actual
Franco Guidi Polanco (PUCV-EII)

25-05-14

38

Ejemplo de uso de una lista (versin clsica)


miLista.currValue():

miLista=(12, 99, 22, 50, 30)


Dato actual
22
miLista.remove():

miLista=(12, 99, 50, 30)


(Nuevo) dato actual
22
miLista.setFirst():

miLista=(12, 99, 50, 30)


Dato actual
Franco Guidi Polanco (PUCV-EII)

25-05-14

39

Interfaz extendida para la lista clsica


public interface ExtendedList {
public void clear();
//
public void insert(Object item); //
public void append(Object item); //
public Object remove();
//
public void setFirst();
//
public void next();
//
public void prev();
//
public int length();
//
public void setPos(int pos);
//
public void setValue(Object val);//
public Object currValue();
//
public boolean isEmpty();
//
public boolean eol();
//
public String toString();
//
}

Elimina todos los elem.


Inserta elem. en act.
Agrega elem. al final
Saca/retorna elem.
Setea act. en 1ra pos.
Mueve act. a sig. pos.
Mueve act. a pos. prev.
Retorna largo
Setea act. a pos
Setea elemento
Retorna elemento
True: lista vaca
True: act en end of list
Retorna lista de elem.

Nota: pos.=posicin; act.=posicin actual; sig.:siguiente; prev.:previa


Franco Guidi Polanco (PUCV-EII)

25-05-14

40

Implementacin de la lista clsica


vLa conveniencia de una u otra implementacin depende de
las operaciones definidas en la interfaz.
vInterfaz elemental:
Implementacin basada en lista simplemente enlazada
Implementacin basada en arreglos
Implementacin basada en lista doblemente enlazada
(sobredimensionada)

vInterfaz extendida:
Implementacin basada en arreglos
Implementacin basada en lista doblemente enlazada
Implementacin basada en lista simplemente enlazada

Franco Guidi Polanco (PUCV-EII)

25-05-14

41

Implementacin de la lista clsica basada en


arreglos
vUsa un arreglo para almacenar los elementos de la
lista.
vLos elementos son almacenados en posiciones
contiguas en el arreglo.
vEl elemento i de la lista se almacena en la celda
i-1 del arreglo.
vLa cabeza de la lista siempre est en la primera
posicin del arreglo (0).
vEl mximo nmero de elementos en la lista se
define al crear el arreglo.

Franco Guidi Polanco (PUCV-EII)

25-05-14

42

Insercin en lista basada en arreglos

Insertar 23
13 12 20
0

(a)

13 12 20

(b)

23 13 12 20

(c)
Franco Guidi Polanco (PUCV-EII)

25-05-14

43

Comparacin entre implementaciones de listas


vLas listas basadas en arreglos tienen la desventaja
de que su nmero de elementos debe ser
predeterminado.
vCuando estas listas tienen pocos elementos, se
desperdicia espacio.
vLas listas enlazadas no tienen lmite de nmero
mximo de elementos (mientras la memoria lo
permita).

Franco Guidi Polanco (PUCV-EII)

25-05-14

44

Comparacin entre implementaciones de listas


vLas listas basadas en arreglos son ms rpidas que
aquellas basadas en listas enlazadas para el
acceso aleatorio por posicin.
vLas operaciones de insercin y eliminacin son
ms rpidas en las listas enlazadas.
vEn general, si el nmero de elementos que
contendr una lista es muy variable o desconocido,
es mejor usar listas enlazadas.

Franco Guidi Polanco (PUCV-EII)

25-05-14

45

Uso de listas
vSupongamos las siguientes implementaciones de la lista:
LList, implementa List mediante una lista
simplemente enlazada
AList, implementa List mediante un arreglo
vReferenciamos la lista por medio de su interfaz:
...
List lista = new LList(); // Implementacin seleccionada
lista.insert( Hola );
lista.insert( chao );
lista.setFirst();
while( !lista.eol() ){
System.out.println( (Sring)lista.currValue());
lista.next();
}
lista.setFirst();
String eliminado = (String) lista.remove()
...
Franco Guidi Polanco (PUCV-EII)

25-05-14

46

Uso de listas (cont.)


vSi en el programa anterior ahora se desea utilizar otra
implementacin de lista, slo debe cambiarse la clase a
instanciar.
...
List lista = new AList(); // Implementacin seleccionada
lista.insert( Hola );
lista.insert( chao );
lista.setFirst();
while( !lista.eol() ){
System.out.println( (Sring)lista.currValue());
lista.next();
}
lista.setFirst();
String eliminado = (String) lista.remove()
...
Franco Guidi Polanco (PUCV-EII)

25-05-14

47

Pilas
vEs un tipo restringido de lista, en donde los
elementos slo pueden ser insertados o removidos
desde un extremo, llamado top.
vSe le llama tambin Stack o Lista LIFO (Last In,
First Out).
vLa operacin para insertar un nuevo elemento se
denomina push.
vLa operacin para remover un elemento se denomina
pop.

Franco Guidi Polanco (PUCV-EII)

25-05-14

48

Interfaz para la Pila

public interface Stack {


public void clear();
// Remueve todos los objetos
public void push(Object it); // Agrega objeto al tope
public Object pop();
// Saca objeto del tope
public Object topValue();// Retorna objeto en el tope
public boolean isEmpty();
// True: pila vaca
}

Franco Guidi Polanco (PUCV-EII)

25-05-14

49

Ejemplo de uso de una pila


v pila.push(4):

vpila.push(14):

top

vpila.push(1):
1
14
4

Franco Guidi Polanco (PUCV-EII)

top

14
4
vpila.pop():
1

top
14
4

25-05-14

top
(nuevo)

50

Implementacin de una pila mediante lista


simplemente enlazada
top

null

pila.push(4)
4

top

pila.push(14)
14

null

Se inserta y remueve
siempre el primer
elemento:
no se requiere nodo
fantasma

top

null

pila.pop()
4

top
Franco Guidi Polanco (PUCV-EII)

null
25-05-14

51

Implementacin de una pila mediante un arreglo

top=4

vEn esta clase, por conveniencia, se usa una


variable top, que siempre est 1 posicin ms
adelante del elemento superior de la pila.

Franco Guidi Polanco (PUCV-EII)

25-05-14

52

Ejercicio pilas
vProponga implementaciones de la pila:
Basada en un arreglo
Basada en una lista simplemente enlazada

Franco Guidi Polanco (PUCV-EII)

25-05-14

53

Colas
vEs un tipo restringido de lista, en donde los
elementos slo pueden ser agregados al final, y
removidos por el frente.
vSe le llama tambin Queue o Lista FIFO (First In,
First Out).
vLa operacin para agregar un nuevo elemento se
denomina enqueue.
vLa operacin para remover un elemento se denomina
dequeue.

Franco Guidi Polanco (PUCV-EII)

25-05-14

54

Interfaz para la Cola

public interface Queue {


public void clear(); // Remueve todos los objetos
public void enqueue(Object it);// Agrega obj. al final
public Object dequeue(); // Saca objeto del frente
public Object firstValue(); // Retorna obj. del frente
public boolean isEmpty(); // Retorna V si cola vaca
}

Franco Guidi Polanco (PUCV-EII)

25-05-14

55

Ejemplo de uso de una cola


v cola.enqueue( 20 )

cola=(20)
v cola.enqueue( 15 )

cola=(20, 15)
v cola.enqueue( 40 )

cola=(20, 15, 40)


v cola.dequeue()

cola=(15, 40)
v cola.dequeue()

20

cola=(40)
15
Franco Guidi Polanco (PUCV-EII)

25-05-14

56

Cola basada en lista simplemente enlazada

25

null

front

rear

vEs conveniente mantener una referencia al ltimo


elemento de la cola (facilita operacin enqueue).

Franco Guidi Polanco (PUCV-EII)

25-05-14

57

Cola basada en arreglos (cont.)


vAproximacin simple: almacenar los n elementos de
la cola en las n primeras posiciones del arreglo.
rear=3

Sacar del frente:


5

rear=2

Problema: lentitud de procedimiento dequeue (sacar


primer elemento).
Franco Guidi Polanco (PUCV-EII)

25-05-14

58

Cola basada en arreglos (cont.)


vAproximacin mejorada: al hacer dequeue, no
desplazar elementos, sino asumir que el frente de la
cola se desplaza.
front=0

rear=3

Sacar del frente:


front=1 rear=3

Problema: Al sacar y agregar elementos, rear llega a la ltima


posicin del arreglo y la cola no puede crecer, aun cuando existan
posiciones libres al comienzo.
Franco Guidi Polanco (PUCV-EII)

25-05-14

59

Cola basada en arreglos* (cont.)


vArreglo circular: Pretender que el arreglo es circular, y
permitir que la cola contine directamente de la ltima
posicin del arreglo a la primera.

front=0

5
8

2
4

Franco Guidi Polanco (PUCV-EII)

2
rear=3

25-05-14

Funcin de avance
Dados:
pos: posicin actual
size: tamao arreglo
pos=(pos+1);
if (pos>=size)
pos=0;

60

Cola basada en arreglos* (cont.)


v Problema de arreglo circular:
Si front es igual a rear, implica que hay 1 elemento.
Luego, rear est una posicin detrs de front implica que la cola
est vaca.
Pero si la cola est llena, rear tambin est una posicin detrs de
front.
v Problema: Cmo reconocer cuando una cola est vaca o llena?
v Solucin: Usar un arreglo de n posiciones, para almacenar como
mximo n-1 elementos.

Franco Guidi Polanco (PUCV-EII)

25-05-14

61

Cola basada en arreglos* (cont.)


vPor conveniencia, se usa una variable front para
apuntar a la posicin precedente al elemento
frontal.
vLa cola est vaca cuando front=rear.
vLa cola est llena cuando rear est justo detrs
de front, o sea cuando la funcin de avance
indica que de aumentar rear en 1, se llegara a
front.

Franco Guidi Polanco (PUCV-EII)

25-05-14

62