You are on page 1of 5

Pg : 1

Ing Oliver A. Vilca H.

CURSO: ESCTRUCTURA DE DATOS Y ALGORITMOS


Listas Enlazadas
Vamosaempezarconuntemaquesueleparecercomplicado,sinembargo,noesalgodeotromundo.C++estdiseadoparala
programacinorientadaaobjetos(POO),yeneseparadigma,todaslasentidadesquesepuedemanejarsonobjetos.
LospunterosenC++sirvenparasealarobjetos,ytambinparamanipularlos.Unpunteroesuntipoespecialdeobjetoque
contiene,nimsnimenosque,ladireccindememoriadeunobjeto(unchar,unint,unfloat,unarray,unaestructura,una
funcinuotropuntero),lospunterosqueapuntenatiposdeobjetosdistintos,serntiposdiferentes.Porejemplo,nosepuede
asignaraunpunteroacharelvalordeunpunteroaint.
#include<span class="code-keyword"><iostream></span>
using namespace std;
main()
{
int a = 50;
// Declara e inicializa la variabla 'a'
cout<<"El valor de 'a': "<<a<<endl; // Muestra el valor de 'a'
cout<<"Direccin de memoria de 'a': "<<&a<<endl;
cout<<endl;
int *b;
// Declara un puntero a entero 'b'
b = &a;
// Transfiere la direccin de 'a' al puntero 'b'
*b = 100;
// Cambia el valor de 'a' usando el puntero '*b'
cout<<"El valor de la variable apuntado por *b: "<<*b<<endl;
cout<<"Content del puntero 'b': "<<b<<endl;
cout<<"Direccin de memoria del puntero 'b': "<<&b<<endl;
cout<<endl;
int **c;
// Declara un puntero a puntero entero 'c'
c = &b;
// Transfiere la direccin de 'b' al puntero a puntero 'c'
**c = 200;
// Cambia el valor de 'a' usando el puntero a puntero 'c'
cout<<"El valor de 'a' usando **c: "<<*cc<<endl;
cout<<"Contenido del puntero 'c': "<<c<<endl;
}

Ahora que se tiene una nocin clara de punteros, se continuar con listas enlazadas.
Listas enlazadas
Es una estructura de datos bsica y puede ser usada para implementar otras estructuras de datos, consiste en una
secuencia de nodos, en los que se guardan campos de datos arbitrarios (informacin requerida) y una o dos referencias, enlaces o
punteros al nodo anterior y/o siguiente. Si no hay mas nodos el puntero apunta a un tipo vacio denominado NULL (nulo) o un
nodo ficticio para evitar que accidentalmente se apunte a un lugar arbitrario de la memoria. Las listas enlazadas son estructuras de
datos semejantes a los arrays salvo que el acceso a un elemento no se hace mediante un ndice sino mediante un puntero. La
asignacin de memoria es hecha durante la ejecucin.
La ventaja principal de las listas frente a los arrays es que las listas proveen una forma eficiente de mover nodos,
flexibilidad que se gana a costa del acceso arbitrario de un nodo de la lista, porque la nica forma de acceder a la lista es mediante
los enlaces desde el inicio. En un array los elementos estn contiguos en la memoria, en una lista los elementos estn dispersos.
Las listas enlazadas pueden ser implementadas en muchos lenguajes, Lisp y Schemen tiene estructuras de datos ya
construidas, junto con operaciones para acceder a las listas enlazadas. Lenguajes imperativos u orientados a objetos tales como C
C++ y Java, respectivamente, disponen de referencias para crear listas enlazadas.
Lista enlazada simple.
El puntero siguiente del ltimo elemento debe apuntar a NULL (el fin de la lista).
El puntero pInicio contendr la direccin del primer elemento de la lista.
Primero se crea la estructura de los nodos de una lista enlazada. Tiene dos miembros, el primero es string Nombre el cual
almacenara el nombre de un estudiante, jugador de ftbol, etc, en general una variable que almacena informacin, el segundo es:
Nodo* Siguiente, el cual guardar la referencia al siguiente nodo.
Se crea el formato de un nodo denominado 'Nodo'
struct Nodo
{
string Nombre;
Nodo* Siguiente;
};
Nodo* pInicio = NULL;

Se crea un puntero a un nodo, el nodo aun no existe y por lo


tanto la lista se considera vacia.

pInicio = new Nodo();

Se crea un nuevo nodo y se hace que pInicio lo apunte.

pInicio->Nombre = Sistemas;

Se copia la cadena Sistemas al nodo

Pg : 2

Ing Oliver A. Vilca H.

Recorrido de una lista.


Recuerde de nuevo el tren. Imaginemos un conductor (no es un trmino tcnico) que slo pueden ingresar al tren a travs de la
locomotora (nodo raz o inicio), y se puede pasar al siguiente vagn (coche), siempre y cuando el anterior coche est conectado al
siguiente. As es como el programa recorrer la lista enlazada. El conductor ser un puntero a nodo, y primero apuntar a la raz o
inicio, y luego, si el nodo raz apunta a un siguiente nodo, se har que el "conductor" apunte a dicho siguiente nodo. De este
modo, la lista puede ser recorrida, siempre y cuando haya un siguiente nodo el recorrido continuar. Y una vez que llegue a un
puntero nulo (o nodo ficticio) entonces ser al final de la lista, significa que no hay ms nodos (coches de tren).
El recorrido se puede aprovechar para imprimir todos los nodos de una lista enlazada, hay que tener cuidado porque es necesario
imprimir el ltimo nodo de la lista despus que el bucle while termina.
conductor = pInicio;
// Que 'conductor' apunte a la raiz
if ( conductor != NULL ) { //Asegura que hay un nodo para iniciar
while ( conductor->Siguiente != NULL ) {
cout<< conductor->Nombre;
conductor = conductor->Siguiente;
}
cout<< conductor->Nombre;
}

La impresin final es necesario, porque el buble while no lo har ni aun cuando alcance el nodo final. Se puede evitar esta
redundancia, permitiendo que el conductor camine fuera del ltimo vagn (la parte posterior del tren). Suicidio para el conductor
si se tratara de una persona real, pero el cdigo es ms sencillo, ya que tambin nos permite eliminar la comprobacin inicial de
NULL (si la raz es nula, el conductor se pondr de inmediato en NULL y el bucle nunca inicia):
conductor = pInicio;
while ( conductor != NULL ) {
cout<< conductor->Nombre;
conductor = conductor->Siguiente;
}

Un nodo puede ser una clase.


Se puede implementar la estructura de datos nodo utilizando clases del C++ y aprovechar sus beneficios como la
implementacin de un nodo template:
#include <iostream>
using namespace std;
template<class T> class Nodo
{
public:
Nodo<T> *Siguiente;
T Dato;
Nodo();
Nodo(const T& aux);
};
template<class T> Nodo<T>::Nodo() // Constructor por defecto
{
this->Siguiente = NULL;
}
// Constructor para establecer el valor de 'Dato'
template<class T> Nodo<T>::Nodo(const T& aux)
{
this->Dato = aux;
}
int main()
{
Nodo<char> *p,*q;
p = new Nodo<char>('A');
q = new Nodo<char>('B');
p->Siguiente = q;
cout << "p: " << p->Dato << endl;
// "A"
cout << "q: " << q->Dato << endl;
// "B"
cout << "p->Siguiente: "<<p->Siguiente->Dato<<endl;
}

Clase lista enlazada simple.


#include <iostream>
using namespace std;

// "B"

Ing Oliver A. Vilca H.

Pg : 3

struct Nodo
// Nodo de la Lista
{ string Elemento; // Dato o elemento del Nodo
Nodo *Siguiente; // Puntero al siguiente Nodo
};
class Lista // Clase q administra la lista
{
Nodo *Primero; // Referencia al primer elemento
public:
Lista();
void Insertar(string);
//void Borrar(string);
void Mostrar(void);
void Invertir(void);
Nodo* ObtenerPrimero(void);
};
Lista::Lista() //Constructor
{
Primero=NULL;
}
Nodo* Lista::ObtenerPrimero(void)
{
return Primero;
}
void Lista::Insertar(string s)
{
Nodo *temp;
temp = new Nodo();
temp->Elemento = s;
temp->Siguiente = Primero;
Primero=temp;
}
void Lista::Mostrar(void)
{
Nodo *tmp = Primero;
while( tmp != NULL )
{
cout<<tmp->Elemento<<" ";
tmp=tmp->Siguiente;
}
cout<<endl;
}
void Lista::Invertir(void)
{
Nodo *x = Primero;
Nodo* siguiente = x;
Nodo* anterior = NULL;
while(x!=NULL)
{
siguiente=x->Siguiente; //Desplaza
x->Siguiente=anterior; //INVIERTE
anterior=x; //Desplaza
x=siguiente; //Desplaza
}
Primero = anterior;
}
int main()
{
Lista ListaSchindler;
ListaSchindler.Insertar("Ana");
ListaSchindler.Insertar("Bety");
ListaSchindler.Insertar("Chavo");
ListaSchindler.Insertar("Erick");
ListaSchindler.Invertir();
ListaSchindler.Mostrar();
Nodo *aux;
aux = ListaSchindler.ObtenerPrimero();
cout<<aux->Elemento<<endl;
aux = aux->Siguiente->Siguiente;
cout<<aux->Elemento<<endl;
return 0;
}

Ejercicios propuestos:
1. Dibuje la lista enlazada con los nodos insertados..
2. Al final del cdigo main(), inserte un nuevo nodo con su nombre entre los nodos Chavo y Erick, es decir, despus de la
referencia aux (a la derecha de aux). Para comprobar muestre el elementos de la lista.
3. Implemente la funcin miembro Borrar el cual recibe como parmetro el nombre del nodo a borrar ejemplo
ListaSchindler.Borrar("Bety"). Compruebe su respuesta mostrando la lista con el nodo borrado.

Ing Oliver A. Vilca H.

Clase lista enlazada doble.


#include <iostream>
using namespace std;
struct Nodo{
string Dato;
Nodo *siguiente;
Nodo *anterior;
};
class ListaDoble{
Nodo *primero;
public:
ListaDoble();
void Mostrar();
void Insertar(string);
Nodo* ElPrimero();
void Buscar(string);
};
ListaDoble::ListaDoble(){ primero = NULL; }
void ListaDoble::Mostrar(void)
{
Nodo *temp = primero;
while(temp!=NULL){
cout<<temp->Dato<<" ";
temp=temp->siguiente;
}
cout<<endl;
}
void ListaDoble::Insertar(string s){
Nodo *temp;
temp = new Nodo();
temp->Dato = s;
temp->anterior = NULL;
if(primero == NULL){
temp->siguiente = NULL;
}else{
temp->siguiente = primero;
primero->anterior = temp;
}
primero = temp;
}
Nodo* ListaDoble::ElPrimero(){
return primero;
}
void ListaDoble::Buscar(string s){
Nodo *temp = primero;
while(temp!=NULL && temp->Dato!=s){
temp=temp->siguiente;
}
if(temp!=NULL) cout<<"Encontrado"<<endl;
else cout<<"No encontrado"<<endl;
}
main(int argc, char *argv[])
{
cout<<"LISTAS DOBLEMENTE ENLAZADAS"<<endl;
Nodo *aux;
ListaDoble MiLista;
MiLista.Insertar("Diego_de_la_Vega");
MiLista.Mostrar();
MiLista.Insertar("Clark_Kent");
MiLista.Mostrar();
MiLista.Insertar("Bruno_Diaz");
MiLista.Mostrar();
MiLista.Insertar("Abel");
MiLista.Mostrar();
MiLista.Buscar("Bruno_Diaz");
aux = MiLista.ElPrimero();
aux = aux->siguiente->siguiente;
aux = aux->anterior->siguiente;
cout<<aux->Dato<<endl;
}

Pg : 4

Pg : 5

Ing Oliver A. Vilca H.

Ejercicios listas doblemente enlazadas:


1. Dibuje la lista enlazada con los nodos insertados..
2. Al final del cdigo main(), inserte un nuevo nodo con su nombre entre Clark_kent y Diego_de_la_Vega, es decir, despus de la
referencia aux (a la derecha de aux).

Ejercicios propuestos para exmenes:


1.

Dado el siguiente cdigo:

[6p]

struct Nodo { int edad; Nodo* der; Nodo* izq; };


struct Nodo* Adan; struct Nodo* Cain; struct Nodo* Abel;
Adan = new Nodo(); Cain = new Nodo(); Abel = new Nodo();
Adan->edad = 930; Adan->izq = Cain; Adan->der = Abel;
Cain->edad = 101; Cain->izq = NULL; Cain->der = NULL;
Abel->edad = 100; Abel->izq = NULL; Abel->der = Abel;

a) Dibuje la interelacin de los nodos:

b) Cules de las siguientes expresiones tienen el valor NULL?


A)
C)
E)

Adan->izq
Adan->izq->izq
Abel->der->der->izq

B)
D)
F)

c) Indique lo qu muestra el siguiente cdigo:


A) 0

2.

B) 930

Dada la siguiente clase:

Suponga que

C) 101

Adan->der
Adan->der->der
Ninguna de las Anteriores.

cout << Abel->der->der->edad;

D) 100

E) NULL

F) No compila.

[5p]

class ListaDoble
{ struct Nodo { char elemento;
struct Nodo *siguiente;
struct Nodo *anterior; };
private: struct Nodo *primero;
public: ListaDoble(void) { primero = NULL; } // Constructor: La lista inicia vaca.
//... el resto de funciones miembro ...
};
deseamos insertar un nodo en la clase ListaDoble, el nuevo nodo est dado por el siguiente puntero:

struct Nodo *NuevoNodo; NuevoNodo->elemento='Y';

Y la posicin en la que se requiere insertar es justo ANTES (a la IZQUIERDA) del puntero current. Como se muestra en la
figura:
struct Nodo *current;
cu rren t
A

Figura 1: Antes de insertar el nuevo nodo con el elemento "Y"

Escriba un cdigo apropiado para insertar el nodo en la lista. No escriba el cdigo entero de la funcin de insercin solo es
necesario 4 lneas para reordenar los puntero. Usted puede asumir que estamos insertando en la mitad de la lista, no en la primera
ni en la ltima posicin.

You might also like