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

Estructura de Datos Bsicas Listas Enlazadas

Karim Guevara Puente de la Vega


kguevara72@gmail.com UNSA, 2012

Agenda

Introduccin. Listas enlazadas genricas (LEG)

La clase NodoLEG Insercin de elementos Borrado de elementos Representacin enlazada vs. secuencial.

LEG con referencias al primer y ltimo nodo LEG circular LEG doblemente enlazada LEG ordenada

Objetivos

El objetivo general de este tema es estudiar la representacin enlazada de un grupo o coleccin de objetos como una alternativa a la representacin secuencial:

Representar en C++ un grupo o coleccin de elementos mediante una lista enlazada de nodos. Comparacin de la representacin enlazada y la secuencial Incidir en el mecanismo de genericidad de C++ Implementacin de distintos tipos de listas en base a criterios de eficiencia y claridad en su diseo

Introduccin

Cmo se almacena computador?

la

informacin

en

el

La memoria est compuesta por unidades bsicas: bits. El microprocesador, y por lo tanto nuestro programa, slo puede manejar directamente bytes o grupos de bytes. Cada byte tiene una direccin: direccin de memoria.

INTRODUCCIN La representacin secuencial

La representacin secuencial la proporciona el tipo array

Coste constante para acceder al i-simo elemento del grupo: v[i]. Coste de insertar un elementos
P.e. insertar un elemento en la primera posicin de un array. Es necesario desplazar todos los elementos del array para dejar un hueco en la primera posicin El coste est en funcin del tamao del array (lineal respecto al nmero de elementos del array)

Coste de eliminar un elemento: en funcin del tamao del array (si se quiere mantener el orden de los elementos)

INTRODUCCIN La representacin enlazada

Una representacin enlazada de un grupo de elemtnos de un cierto tipo es una lista enlazada de nodos, es decir, una secuencia de odos situados en la memoria dinmica y conectados entre s P.e. lista de enteros {4, 8, 5, 3, 2}
Representacin secuencial: Representacin enlazada:
Dato Nodo

4
Referencia al siguiente nodo

2
NULL

LISTAS ENLAZADAS GENRICAS La clase NodoLEG

Un nodo tiene dos atributos:

El dato, de tipo genrico (para poder guardar cualquier tipo de objeto) Una referencia al nodo siguiente
template <class E> class NodoLEG { private: E dato; NodoLEG<E> *siguiente; public: NodoLEG(E dato, NodoLEG<E> *sig=NULL) { this->dato = dato; this->siguiente = sig; } ~NodoLEG( ){this->dato = 0; this->siguiente = NULL; } };

LISTAS ENLAZADAS GENRICAS

Una lista enlazada requiere, como mnimo, una referencia al primer nodo de la lista:
NodoLEG<E> *primero;

Cuando la lista esta vaca, el atributo primero punta a null


primero = NULL;

LEG
primero
NULL

LISTAS ENLAZADAS GENRICAS Implementacin de una LEG


template <class E> class LEG { private: NodoLEG<E> *primero; int tamanio; public:
// El constructor crea la lista vaca

Referencia al primer nodo de la lista

LEG() { primero = null; tamanio = 0; } ... };

En una lista podemos incluir un atributo que indique el nmero de elementos de la lista.

LISTAS ENLAZADAS GENRICAS Insertar un elemento en la LEG

Lo ms eficiente es insertar al principio de la lista, pues tenemos una referencia al primer nodo P.e.: queremos insertar el elemento 1 en la siguiente lista:
LEG
primero

3
NULL

Paso 1

crear el nodo a insertar:


NodoLEG<E> *nuevo = new NodoLEG<E>(1); nuevo

1
NULL

10

LISTAS ENLAZADAS GENRICAS Insertar un elemento en la LEG


Paso 2

hacer que el nodo siguiente del nuevo nodo sea el primero de la lista: nuevo->siguiente = primero;
nuevo
1

LEG
primero 2 3
NULL

Paso 3

hacer que primer nodo de la lista sea el nuevo nodo:


nuevo

primero = nuevo;

LEG
11

primero

3
NULL

LISTAS ENLAZADAS GENRICAS Implementacin


Esta instruccin resume los tres ... pasos que hemos visto para insertar template <class E> un elemento en la lista void LEG<E>::insertar(E x) { primero = new NodoLEG<E>(x, primero); tamanio++; } Este bucle muestra la forma template <class E> ostream & operator<<(ostream &o, LEG<E>& l ) { de recorrer los

nodos de una lista

for (NodoLEG<E> *aux = l.primero; aux != null; aux = aux->siguiente) o<<aux->dato <<\n; return o; } ... }
12

LISTAS ENLAZADAS GENRICAS Eliminar un elemento de una LEG

P.e.: eliminar el elemento 2 de la lista:


LEG
primero 1 2 3
NULL

Para eliminar el 2 tenemos que hacer que el siguiente del 1 sea el 3

Tenemos que averiguar, por lo tanto, cul es el nodo anterior del que queremos eliminar
13

LISTAS ENLAZADAS GENRICAS Implementacin


... template <class E> boolean LEG<E>::eliminar(E x) { NodoLEG <E> *aux = primero, *ant = null; while (aux != null && aux->dato != x) { ant = aux; aux = aux->siguiente; } if (aux == null) return false; // Elemento no encontrado if (ant == null) primero = aux->siguiente; else ant->siguiente = aux->siguiente; tamanio--;
delete aux;

return true;

Caso especial: cuando el nodo a borrar es el primero de la lista

}
}
14

LISTAS ENLAZADAS GENRICAS representacin enlazada vs. secuencial


Ventajas representacin secuencial

Desventajas representacin secuencial

Acceso en tiempo constante a cualquier elemento

La insercin y el borrado requieren del desplazamiento de parte (o todas) las componentes del array Reserva a priori de una cantidad de memoria mayor que el amao del grupo

Ejercicio 1: Aadir a la clase LEG un mtodo que inserte un nuevo elemento al final de la lista:
void insertarEnFin(E x);

Cul es el coste del nuevo mtodo?


15

LEG CON REFERENCIAS AL PRIMER Y LTIMO NODO

Cmo se puede mejorar la eficiencia al insertar en la ltimo posicin de la lista?

Podemos guardar en la lista una referencia al ltimo nodo:


LEG primero
ultimo

3
NULL

16

LEG CON REFERENCIAS AL PRIMER Y LTIMO NODO


template <class E> class LEGConUltimo { protected: NodoLEG<E> *primero, *ultimo; int tamanio; public: LEGConUltimo() { primero = ultimo = null; tamanio = 0; } ... ];

17

LEG CON REFERENCIAS AL PRIMER Y LTIMO NODO


... template <class E> void LEGConUltimo<E>::insertarEnFin(E x) {//Coste constante NodoLEG<E> *nuevo = new NodoLEG<E>(x); if (ultimo != null) ultimo->siguiente = nuevo; else primero = nuevo; ultimo = nuevo; tamanio++; } template <class E> void LEGConUltimo<E>::insertar(E x) { primero = new NodoLEG <E> (x, primero); if (ultimo == null) ultimo = primero; tamanio++; } ...

18

LEG CON REFERENCIAS AL PRIMER Y LTIMO NODO


... template <class E> boolean LEGConUltimo<E>::eliminar(E x) { NodoLEG <E> *aux = primero, *ant = null; while (aux != null && aux->dato != x) { ant = aux; aux = aux->siguiente; } if (aux == null) return false; // No encontrado if (ant == null) primero = aux->siguiente; else ant->siguiente = aux->siguiente; if (aux->siguiente == null) ultimo = ant; delete aux; tamanio--; Caso especial: si borramos el ltimo nodo, return true; el ltimo ser ahora el nodo anterior }

19

LEG CIRCULAR

Una alternativa a la LEG con referencia al primer y ltimo nodo es la LEG circular: una LEGConUltimo en la que se obliga a que el siguiente al ltimo nodo sea el primero:
LEG
primero ultimo
Podemos prescindir de la referencia al primer nodo, pues ultimo.siguiente ya apunta al primer nodo

1
20

3
NULL

LEG CIRCULAR
template <class E> class LEGCircular { protected: NodoLEG<E> *ultimo; int tamanio; public: LEGCircular() { ultimo = null; tamanio = 0; } ... };

Referencia al ltimo nodo

21

LEG CIRCULAR
... template <class E> void LEGCircular <E> :: insertar(E x) { NodoLEG<E> *nuevo = new NodoLEG<E> (x); nuevo->siguiente = nuevo; if (ultimo != null) { // Lista no vaca nuevo->siguiente = ultimo->siguiente; ultimo->siguiente = nuevo; } else ultimo = nuevo; // Lista vaca tamanio++; } ... }
22

Ejercicio 2: escribir el mtodo eliminar de la LEGCircular

LEG DOBLEMENTE ENLAZADAS

En las LEG doblemente enlazadas cada nodo, adems de una referencia al nodo siguiente, tiene una referencia al nodo anterior

LEG
primero
NULL

1
NULL

23

LEG DOBLEMENTE ENLAZADAS


template <class E> class NodoLDEG { private:
// Tres atributos

E dato; NodoLDEG<E> *siguiente, *anterior; public:


// constructor

NodoLDEG(E dato, NodoLDEG<E> *s=0, NodoLDEG<E> *a=0) { this->dato = dato; this->siguiente = s; this->anterior = a; } };
24

LEG DOBLEMENTE ENLAZADAS


template <class E> class LDEG { protected: NodoLDEG<E> *primero; int tamanio; public: LDEG() { primero = null; tamanio = 0; } void insertar(E x) { NodoLDEG<E> *nuevo = new NodoLDEG<E>(x, primero, null); if (primero != null) primero->anterior = nuevo; primero = nuevo; tamanio++; } ... };

25

LEG DOBLEMENTE ENLAZADAS


template <class E> boolean LDEG<E>::eliminar(E x) { NodoLDEG<E> *aux = primero; while (aux != null && aux->dato!=x) aux = aux->siguiente; if (aux == null) return false; // Elemento no encontrado if (aux->anterior != NULL) aux->anterior->siguiente = aux->siguiente; else primero = aux->siguiente; if (aux->siguiente != NULL) aux->siguiente->anterior = aux->anterior; delete aux; tamanio--; return true; Ahora no es necesario una variable ant } que apunte al nodo anterior ...
26

LEG ORDENADAS

En una LEG ordenada, los nodos de la lista se mantienen ordenados de acuerdo con un orden determinado:
LEG
primero

4
NULL

Si insertamos el elemento 3

LEG
primero

4
NULL

27

LEG ORDENADAS
template <class E> class LEGOrdenada: public LEG { ... public: void insertar(E x) { NodoLEG<E> *nuevo = new NodoLEG<E>(x); NodoLEG<E> *ant = NULL, *aux = primero; while (aux != NULL && aux->dato < x) { ant = aux; aux = aux->siguiente; } nuevo->siguiente = aux; if (ant != NULL) ant->siguiente = nuevo; else primero = nuevo; tamanio++; } ... }:

28

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