Sie sind auf Seite 1von 26

Leccion 3.

3 LISTAS ENLAZADAS

En Ciencias de la Computación, una lista enlazada es una de las estructuras de datos fundamentales, 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 y una o dos referencias (punteros) al nodo anterior o
posterior. El principal beneficio de las listas enlazadas respecto a los array convencionales es que el
orden de los elementos enlazados puede ser diferente al orden de almacenamiento en la memoria o el
disco, permitiendo que el orden de recorrido de la lista sea diferente al de almacenamiento.

Una lista enlazada es un tipo de dato auto-referenciado porque contienen un puntero o link a otro dato
del mismo tipo. Las listas enlazadas permiten inserciones y eliminación de nodos en cualquier punto de
la lista en tiempo constante (suponiendo que dicho punto está previamente identificado o localizado),
pero no permiten un acceso aleatorio. Existen diferentes tipos de listas enlazadas: Lista Enlazadas
Simples, Listas Doblemente Enlazadas, Listas Enlazadas Circulares y Listas Enlazadas Doblemente
Circulares.

Las listas enlazadas pueden ser implementadas en muchos lenguajes. Lenguajes tales como Lisp y
Scheme tiene estructuras de datos ya construidas, junto con operaciones para acceder a las listas
enlazadas. Lenguajes imperativos u orientados a objetos tales como C o C++ y Java, respectivamente,
disponen de referencias para crear listas enlazadas.

Listas simples enlazadas

La lista enlazada básica es la lista enlazada simple la cual tiene un enlace por nodo. Este enlace apunta
al siguiente nodo en la lista, o al valor NULL o a la lista vacía, si es el último nodo.

Una lista enlazada simple contiene dos valores: el valor actual del nodo y un enlace al siguiente nodo

Aplicaciones de las listas enlazadas


Las listas enlazadas son usadas como módulos para otras muchas estructuras de datos, tales como pilas,
colas y sus variaciones.

El campo de datos de un nodo puede ser otra lista enlazada. Mediante este mecanismo, podemos
construir muchas estructuras de datos enlazadas con listas; esta practica tiene su origen en el lenguaje de
programación Lisp, donde las listas enlazadas son una estructura de datos primaria (aunque no la única),
y ahora es una característica común en el estilo de programación funcional.

A veces, las listas enlazadas son usadas para implementar arrays asociativos, y estas en el contexto de
las llamadas listas asociativas. Hay pocas ventajas en este uso de las listas enlazadas; hay mejores
formas de implementar éstas estructuras, por ejemplo con árboles binarios de búsqueda equilibrados. Sin

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 1


embargo, a veces una lista enlazada es dinámicamente creada fuera de un subconjunto propio de nodos
semejante a un árbol, y son usadas más eficientemente para recorrer ésta serie de datos

Ventajas
Como muchas opciones en programación y desarrollo, no existe un único método correcto para resolver
un problema. Una estructura de lista enlazada puede trabajar bien en un caso pero causar problemas en
otros. He aquí una lista con un algunas de las ventajas más comunes que implican las estructuras de tipo
lista. En general, teniendo una colección dinámica donde los elementos están siendo añadidos y
eliminados frecuentemente e importa la localización de los nuevos elementos introducidos se incrementa
el beneficio de las listas enlazadas.

Lenguajes soportados
Muchos lenguajes de programación tales como Lisp y Scheme tienen listas enlazadas simples ya
construidas. En muchos lenguajes de programación, estas listas están construidas por nodos, cada uno
llamado cons o celda cons. Las celdas cons tienen dos campos: el car, una referencia del dato al nodo, y
el cdr, una referencia al siguiente nodo. Aunque las celdas cons pueden ser usadas para construir otras
estructuras de datos, este es su principal objetivo.

En lenguajes que soportan tipos abstractos de datos o plantillas, las listas enlazadas ADTs o plantillas
están disponibles para construir listas enlazadas. En otros lenguajes, las listas enlazadas son típicamente
construidas usando referencias junto con el tipo de dato record.

En la sección de implementaciones hay un ejemplo completo en C y en Maude

Operaciones sobre listas enlazadas

Cuandos se manipulan listas enlazadas, hay que tener cuidado con no usar valores que hayamos
invalidado en asignaciones anteriores. Esto hace que los algoritmos de insertar y borrar nodos en las
listas sean algo especiales. A continuación se expone el pseudocódigo para añadir y borrar nodos en
listas enlazadas simples, dobles y circulares.

Listas Enlazadas Lineales

Nuestra estructura de datos tendrá dos campos. Vamos a mantener la variables PrimerNodos que
siempre apunta al primer nodo de tal lista, ó nulo para la lista vacía.

record Node {
data // El dato almacenado en el nodo
next // Una referencia al nodo siguiente, nulo para el último nodo
}
record List {
Node PrimerNodo // Apunta al primer nodo de la lista; nulo para la lista
vacía
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 2


El recorrido en una lista enlazada es simple, empezamos por el primer nodo y pasamos al siguiente hasta
que la lista llegue al final.

node := list.PrimerNodo
while node not null {
node := node.next
}

El siguiente código inserta un elemento a continuación de otro en una lista simple. El diagrama muestra
como funciona.

function insertAfter(Node node, Node newNode) {


newNode.next := node.next
node.next := newNode
}

Insertar al principio de una lista requiere una función por separado. Se necesita actualizar PrimerNodo.

function insertBeginning(List list, Node newNode) {


newNode.next := list.firstNode
list.firstNode := newNode
}

De forma similar, también tenemos funciones para borrar un nodo dado ó para borrar un nodo del
principio de la lista. Ver diagrama.

function removeAfter(Node node) {


obsoleteNode := node.next
node.next := node.next.next
destroy obsoleteNode
}
function removeBeginning(List list) {
obsoleteNode := list.firstNode
list.firstNode := list.firstNode.next
destroy obsoleteNode
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 3


Advertimos que BorrarPrincipio pone PrimerNodo a nulo cuando se borra el último elemento de la lista.
Adjuntar una lista enlazada a otra puede resultar ineficiente a menos que se guarde una referencia a la
cola de la lista, porque si no tendríamos que recorrer la lista en orden hasta llegar a la cola y luego añadir
la segunda lista.

EJEMPLO

Recorrido

Definición:

Recorrido simplemente despliega los datos almacenados en el arreglo Info, con ayuda de un segundo
arreglo llamado Indice el cual guarda el orden en el que encuentran enlazados cada uno de los datos.

Explicación:

Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un Ciclo mientras
Apuntador sea diferente de 0, si cumple lo que hace es que despliega la Info[Apuntador], después
Apuntador toma el valor de Indice[Apuntador] (El cual nos indica el siguiente nodo que sigue en la lista)
y hace esto hasta que Apuntador sea igual a 0 (Cuando llega a este punto a llegado al fin de la Lista
Enlazada).

Algoritmo:

Recorrido(Inicio, Info, Indice)

Apuntador ←- Inicio

Repetir mientras Apuntador ≠ Nill

Imprimir Info[Apuntador]

Apuntador ←- Indice[Apuntador]

Fin del ciclo

Salir

Diagrama:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 4


Programa:

#include <conio.h>
#include <iostream.h>
void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp);

void main()
{
char Info[8][2]={{"G"},{"I"},{" "},{"T"},{"O"},{"A"},
{" "},{"T"}};
int Indice[8]={5,7,6,1,-999,3,-999,4};
int Inicio=0,Disp=2;
cout<<"El Recorrido es:\n";
Recorrido(Info,Indice,Inicio,Disp);
getch();
}

void Recorrido(char Info[8][2],int Indice[8],int Inicio,int Disp)


{
int Apuntador=Inicio;
while(Apuntador!=-999)
{
cout<<Info[Apuntador];
Apuntador=Indice[Apuntador];
}
}

Corrida:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 5


Búsqueda

Definición:

La Búsqueda su objetivo es encontrar un dato en el arreglo Info, si lo encuentra lo desplegara en la


pantalla, si no lo encuentra no desplegara nada ya que el dato no se encuentra en el arreglo Info.

Explicación:

Apuntador toma el valor de Inicio, después ve si la condición cumple para efectuar un Ciclo mientras
Apuntador sea diferente de 0, si cumple lo que hace a continuación es la comparación de Elemento (El
dato que vamos a buscar) con Info[Apuntador], cuando lo encuentre lo despliega y sale del método. Si
no, regresa el valor de Apuntador para así saber que no se encontró el dato.

Algoritmo:

Recorrido(Inicio, Info, Indice, Elemento)

Apuntador ←- Inicio

Repetir mientras Apuntador ≠ Nill

Si Elemento = Info[Apuntador] entonces:

Imprimir Info[Apuntador]

Regresa Apuntador

Apuntador ←- Indice[Apuntador]

Fin del ciclo

Regresar Apuntador

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 6


Diagrama:

Programa:

#include <conio.h>
#include <iostream.h>
int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento);

void main()
{
int Info[8]={12,10,0,9,5,3,0,20};
int Indice[8]={5,7,6,1,-999,3,-999,4};
int Inicio=0,Disp=2,Elemento,Res;
cout<<"Que Numero deseas buscar?";
cin>>Elemento;
Res=Busqueda(Info,Indice,Inicio,Disp,Elemento);
if(Res==-999)
cout<<"Dato No Encontrado...";
getch();
}

int Busqueda(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento)


{
int Apuntador=Inicio;
while(Apuntador!=-999)
{
if(Elemento==Info[Apuntador])
{
cout<<"Numero "<<Info[Apuntador]<<" encontrado...";
return Apuntador;
}
Apuntador=Indice[Apuntador];

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 7


}
return Apuntador;
}

CORRIDA:

Inserción al Principio

Definición:

La Inserción al Principio básicamente busca si existe algún lugar disponible en el arreglo Info y lo
agrega como primer Nodo si es que es posible.

Explicación:

Hace una comparación para ver si es posible insertar otro Elemento al arreglo Info, para esto checa si
Disp es Diferente de Nulo. Si no cumple con la condición se desplegar “Sobre Carga” ya que no se
puede insertar un Nuevo Elemento. Si es cierto Apuntador toma el valor de Inicio, Disp cambia a
Indice[Disp] ya que el primer Disp tomara el valor del Nuevo Elemento, después de esto solo copia la
información de Elemento al arreglo Info en la posición que guarda Apuntador, Indice[Apuntador] toma
el valor de Inicio y finalmente Inicio toma el valor de Apuntador.

Algoritmo:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 8


InsPr(Inicio, Disp, Info, Indice, Elemento)

Si Disp ≠ Nill entonces:

Apuntador ←- Disp

Disp ←- Indice[Disp]

Info[Apuntador] ←- Elemento

Indice[Apuntador] ←- Inicio

Inicio ←- Apuntador

Si no:

Imprimir “Sobre Carga”

Salir

Diagrama:

Programa:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 9


#include <conio.h>
#include <iostream.h>
void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp);
void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento);

void main()
{
int Info[8]={12,10,0,9,5,3,0,20};
int Indice[8]={5,7,6,1,-999,3,-999,4};
int Inicio=0,Disp=2,Elemento,Res;
cout<<"Lista Original\n";
Recorrido(Info,Indice,Inicio,Disp);
cout<<"Que Numero deseas Insertar?";
cin>>Elemento;
InsPr(Info,Indice,Inicio,Disp,Elemento);
getch();
}

void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp)


{
int Apuntador=Inicio;
while(Apuntador!=-999)
{
cout<<Info[Apuntador]<<endl;
Apuntador=Indice[Apuntador];
}
}

void InsPr(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento)


{
if(Disp!=-999)
{
int Apuntador=Disp;
Disp=Indice[Disp];
Info[Apuntador]=Elemento;
Indice[Apuntador]=Inicio;
Inicio=Apuntador;
Recorrido(Info,Indice,Inicio,Disp);
}
else
cout<<"Overflow...";
}

CORRIDA:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 10


Inserción después de UN Nodo Determinado

Definición:

La Inserción después de un Nodo Determinado básicamente hace lo mismo que la inserción al principio,
la única diferencia es que este recibe la posición del nodo en la que será Insertada. Este Algoritmo se usa
para Inserción Ordenada que mas adelante explicaremos.

Explicación:

Primero confirma que sea posible insertar el Dato, si no es posible solo desplegara “Sobre Carga”. Si es
posible insertar un dato nuevo lo posiciona en la primer posición Disponible en el arreglo Info, después
compara la Nueva Posición (Npos) que le mandamos con Nill si cumple la condición el dato es insertado
en la primer posición, de otra forma se posicionara en la posición que guarde Npos.

Algoritmo:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 11


InsNd(Inicio, Disp, Info, Indice, Elemento, Npos)

Si Disp ≠ Nill entonces:

Apuntador ←- Disp

Disp ←- Indice[Disp]

Info [Apuntador] ←- Elemento

Si Npos = Nill entonces:

Indice[Apuntador] ←- Inicio

Inicio ←- Apuntador

Si no:

Indice[Apuntador] ←- Indice[Npos]

Indice[Npos] ←- Apuntador

Si no:

Imprimir “Sobre Carga”

Salir

Inserción Ordenada

Definición:

La Inserción Ordenada busca la posición en donde será Insertado el Elemento y la posición anterior
donde será Insertado, después de encontrar la posición en la que será Insertado el Elemento nos regresa
ese valor y lo mandamos al método de la Inserción después de un Nodo.

Explicación:

En esta ocasión usaremos dos variables para determinar la posición deseada, comparamos si Inicio es
igual a Nill ó si Elemento es menor al dato que se encuentra en Info[Inicio], si alguna de las dos cumple
regresamos Nill, de esta manera Indicamos que el Elemento será el primero de todo el Arreglo Info, si
no es así Temp tomara el valor de Inicio y Temp2 de la posición que le sigue a Inicio. Hace un ciclo
hasta encontrar la posición en donde se insertara el Nuevo Elemento y va moviéndose de posición con
las variables Temp y Temp2 para así determinar que posición debe de regresar.

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 12


Algoritmo:

InsOrd(Inicio, Info, Indice, Elemento)

Si Inicio = Nill ó Elemento < Info[Inicio] entonces:

Regresar Nill

Temp ←- Inicio

Temp2 ←- Indice[Inicio]

Repetir mientras Temp2 ≠ Nill

Si Elemento < Info[Temp2]

Regresar Temp

Temp ←- Temp2

Temp2 ←- Indice[Temp2]

Regresar Temp

Diagrama:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 13


Programa:

#include <conio.h>
#include <iostream.h>
int InsOrd(int Info[8],int Indice[8],int Inicio,int Elemento);
void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp);
void InsNd(int Info[8],int Indice[8],int Inicio,int Disp, int Elemento, int Npos);

void main()
{
int Info[8]={12,10,0,9,5,3,0,20};
int Indice[8]={5,7,6,1,-999,3,-999,4};
int Inicio=0,Disp=2,Elemento,Res;
cout<<"Lista Original\n";
Recorrido(Info,Indice,Inicio,Disp);
cout<<"Que Numero deseas Insertar?";
cin>>Elemento;
Res=InsOrd(Info,Indice,Inicio,Elemento);
InsNd(Info,Indice,Inicio,Disp,Elemento,Res);
getch();
}

void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp)


{
int Apuntador=Inicio;
while(Apuntador!=-999)
{
cout<<Info[Apuntador]<<endl;
Apuntador=Indice[Apuntador];
}
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 14


void InsNd(int Info[8],int Indice[8],int Inicio,int Disp, int Elemento, int Npos)
{
if(Disp!=-999)
{
int Apuntador=Disp;
Disp=Indice[Disp];
Info[Apuntador]=Elemento;
if(Npos==-999)
{
Indice[Apuntador]=Inicio;
Inicio=Apuntador;
}
else
{
Indice[Apuntador]=Indice[Npos];
Indice[Npos]=Apuntador;
}

Recorrido(Info,Indice,Inicio,Disp);
}
else
cout<<"Overflow...";
}

int InsOrd(int Info[8],int Indice[8],int Inicio,int Elemento)


{
int Temp=-999,Temp2;
if(Inicio==Temp||Elemento<Info[Inicio])
return Temp;
Temp=Inicio;
Temp2=Indice[Inicio];
while(Temp2!=-999)
{
if(Elemento<Info[Temp2])
return Temp;
Temp=Temp2;
Temp2=Indice[Temp2];
}
return Temp;
}

CORRIDA:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 15


Eliminación por Búsqueda
Definición:

La Eliminación simplemente cambia los nodos para que el dato que se desea eliminar sea el primer
disponible, de esta forma ya no estará en el Arreglo de Info.

Explicación:

Lo primero que hace es ver si existe algún dato en la lista para eliminar, si Inicio es igual a Nill entonces
solo desplegara “Imposible Eliminar”. De otra formas cambiar de Posición en Posición hasta encontrar
el Elemento que sea desea Eliminar con ayudar de dos variables que guardan la Posición actual y la
anterior en donde se encuentre el dato. Ya que lo encuentra cambia ese dato como la primera posición
Disponible y lo apunta al siguiente nodo disponible. Si no encuentra el dato simplemente desplegara
“Dato no encontrado”

Algoritmo:

EliBusq(Inicio, Info, Indice, Elemento)

Temp ←- Inicio

Si Temp = Nill

Imprimir “Lista Vacia… Imposible Eliminar” y Retornar

Repetir mientras Temp ≠ Nill

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 16


Si Elemento = Info[Temp] entonces:

Si Temp = Inicio entonces:

Inicio ←- Indice[Inicio]

Si no:

Indice[Temp2] ←- Indice[Temp]

Indice[Temp] ß Disp

Disp ←- Temp

Recorrido(Inicio, Info, Indice) y Retornar

Si no:

Temp2 ←- Temp

Temp ←- Indice[Temp]

Imprimir “Dato no encontrado… Imposible Eliminar” y Retornar

Diagrama:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 17


Programa:

#include <conio.h>
#include <iostream.h>
void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp);
void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento);

void main()
{
int Info[8]={12,10,0,9,5,3,0,20};
int Indice[8]={5,7,6,1,-999,3,-999,4};
int Inicio=0,Disp=2,Elemento,Res;
cout<<"Lista Original\n";
Recorrido(Info,Indice,Inicio,Disp);
cout<<"Que Numero deseas Eliminar?";
cin>>Elemento;
EliBusq(Info,Indice,Inicio,Disp,Elemento);
getch();
}

void Recorrido(int Info[8],int Indice[8],int Inicio,int Disp)


{
int Apuntador=Inicio;
while(Apuntador!=-999)
{
cout<<Info[Apuntador]<<endl;
Apuntador=Indice[Apuntador];
}
}

void EliBusq(int Info[8],int Indice[8],int Inicio,int Disp,int Elemento)


{
int Temp=Inicio,Temp2;
if(Temp==-999)
{
cout<<"Lista Vacia... Imposible Eliminar";
return;
}
while(Temp!=-999)
{
if(Elemento==Info[Temp])
{
if(Temp==Inicio)
Inicio=Indice[Inicio];
else
Indice[Temp2]=Indice[Temp];
Indice[Temp]=Disp;
Disp=Temp;
Recorrido(Info,Indice,Inicio,Disp);
return;
}
else
{
Temp2=Temp;
Temp=Indice[Temp];

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 18


}
}
cout<<"Dato no encontrado... Imposible Eliminar";
return;
}

CORRIDA:

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 19


APENDICE
Codigo de Listas enlazadas en C++

#include <stdio.h>
#include <conio.h>
#include <iomanip.h>
#include <iostream.h>

class Alumno
{
private:
char Nombre[10][30];
int N_control[10],Edad[10],Indice1[10],Indice2[10],Inicio,Fin,Disp;
public:
//Constructor
Alumno()
{
int i,j;
Inicio=0;
Fin=0;
Disp=1;
Indice1[Inicio]=-999;
Indice2[Fin]=-999;
for(i=1,j=2;i<9;i++,j++)
Indice1[i]=j;
Indice1[9]=-999;
}

//Funcion de Recorrido
void Recorrido(int op)
{
int i=0,Temp;
if(op==1)
{
Temp=Indice1[Inicio];
if(Temp!=-999)
{
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
while(Temp!=-999)
{
if(i==(int(Edad[Inicio]/2)))
{
N_control[Inicio]=N_control[i];
strcpy(Nombre[Inicio],Nombre[i]);
}
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
Temp=Indice1[Temp];
i++;
}
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 20


else
cout<<"Lista Vacia...";
}
if(op==2)
{
Temp=Fin;
if(Edad[Inicio]!=0)
{
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
while(Temp!=-999&&i<Edad[Inicio])
{
if(i==(int(Edad[Inicio]/2)))
{
N_control[Inicio]=N_control[i];
strcpy(Nombre[Inicio],Nombre[i]);
}
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
Temp=Indice2[Temp];
i++;
}
}
else
cout<<"Lista Vacia...";
}
}

//Funcion de Busqueda Sobrecargada para un Dato Entero


int Busqueda(int Elem)
{
if(Elem<N_control[Inicio])
{
int Temp=Indice1[Inicio];
while(Temp!=-999)
{
if(Elem==N_control[Temp])
{
gotoxy(1,10);
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if(Elem==N_control[Temp])
{
gotoxy(1,10);
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
return Temp;

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 21


}
else
Temp=Indice2[Temp];
}
}
return -999;
}

//Funcion de Busqueda Sobrecargada para una Cadena de Caracteres


int Busqueda(char Elem[30])
{
if((strcmp(Elem,Nombre[Inicio]))<0)
{
int Temp=Indice1[Inicio];
while(Temp!=-999)
{
if((strcmp(Elem,Nombre[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
return Temp;
}
else
Temp=Indice1[Temp];
}
}
else
{
int Temp=Fin;
while(Temp!=-999)
{
if((strcmp(Elem,Nombre[Temp]))==0)
{
gotoxy(1,10);
cout<<"Numero de Control"<<setw(19)<<"Nombre del Alumno"<<setw(5)<<"Edad"<<endl;
cout<<setw(9)<<N_control[Temp]<<setw(22)<<Nombre[Temp]<<setw(9)<<Edad[Temp]<<endl;
return Temp;
}
else
Temp=Indice2[Temp];
}
}
return -999;
}

//Funcion Sobrecargada de Orden para un Dato Entero


int Enca(int E_nc)
{
int Temp=Indice1[Inicio],Temp2;
if(Temp==-999||E_nc<N_control[Temp])
return -999;
Temp2=Indice1[Indice1[Inicio]];
while(Temp2!=-999)
{
if(E_nc<N_control[Temp2])
return Temp;

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 22


Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}

//Funcion Sobrecargada de Orden para una Cadena de Caracteres


int Enca(char E_nom[30])
{
int Temp=Indice1[Inicio],Temp2;
if(Temp==-999)
return -999;
if((strcmp(E_nom,Nombre[Temp]))<0)
return Temp;
Temp2=Indice1[Indice1[Inicio]];
while(Temp2!=-999)
{
if((strcmp(E_nom,Nombre[Temp2]))<0)
return Temp;
Temp=Temp2;
Temp2=Indice1[Temp2];
}
return Temp;
}

//Funcion para la Insercion en un Lugar Determinado


void InsLug(char E_nom[30],int E_nc,int E_edad,int Npos)
{
if(Disp!=-999)
{
Edad[Inicio]++;
int Temp=Disp;
Disp=Indice1[Disp];
strcpy(Nombre[Temp],E_nom);
N_control[Temp]=E_nc;
Edad[Temp]=E_edad;
if(Npos==-999)
{
Indice1[Temp]=Indice1[Inicio];
if(Indice2[Fin]==-999)
{
Indice2[Temp]=Fin;
Fin=Temp;
}
else
{
Indice2[Temp]=Indice1[Inicio];
Indice2[Indice1[Inicio]]=Temp;
}
Indice1[Inicio]=Temp;
}
else
{
Indice1[Temp]=Indice1[Npos];
if(Fin==Npos)
{
Indice2[Temp]=Fin;

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 23


Fin=Temp;
}
else
{
Indice2[Temp]=Npos;
Indice2[Indice1[Npos]]=Temp;
}
Indice1[Npos]=Temp;
}
}
else
cout<<"Overflow..."<<endl;
}

//Funcion Sobrecargada para Borrar un Dato Entero


void Borrar(int Elem)
{
int Temp2,Temp=Indice1[Inicio];
if(Temp==-999)
{
cout<<"Lista Vacia... Imposible Eliminar";
return;
}
while(Temp!=-999)
{
if(Elem==N_control[Temp])
{
Edad[Inicio]--;
if(Temp==Indice1[Inicio])
{
Indice1[Inicio]=Indice1[Indice1[Inicio]];
Indice2[Indice1[Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1[Temp];
Indice2[Indice1[Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no encontrado... Imposible Eliminar";
return;
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 24


//Funcion Sobrecargada para Borrar una Cadena de Caracteres
void Borrar(char Elem[30])
{
int Temp2,Temp=Indice1[Inicio];
if(Temp==Inicio)
{
cout<<"Lista Vacia... Imposible Eliminar";
return;
}
while(Temp!=Inicio)
{
if((strcmp(Elem,Nombre[Temp]))==0)
{
Edad[Inicio]--;
if(Temp==Indice1[Inicio])
{
Indice1[Inicio]=Indice1[Indice1[Inicio]];
Indice2[Indice1[Inicio]]=Inicio;
}
else if(Temp==Fin)
{
Indice1[Temp2]=Indice1[Temp];
Fin=Indice2[Fin];
}
else
{
Indice1[Temp2]=Indice1[Temp];
Indice2[Indice1[Temp2]]=Temp2;
}
Indice1[Temp]=Disp;
Disp=Temp;
return;
}
else
{
Temp2=Temp;
Temp=Indice1[Temp];
}
}
cout<<"Dato no encontrado... Imposible Eliminar";
return;
}
}tec;

main()
{
int op=0,res;
char inom[30];
int in_c,iedad;
while(op!=6)
{
clrscr();
cout<<"\n1) Recorrido por Inicio\n2) Recorrido por Final\n3) Busqueda\n";
cout<<"4) Insercion\n5) Eliminar un Dato\n6) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 25


gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido(1);
break;
case 2:
tec.Recorrido(2);
break;
case 3:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
res=tec.Busqueda(res);
if(res==-999)
cout<<"Dato no encontrado";
break;
case 4:
cout<<"Que nombre quieres Insertar?"<<endl;
gets(inom);
cout<<"Cual es su Numero de Control?"<<endl;
cin>>in_c;
cout<<"Cual es su Edad?"<<endl;
cin>>iedad;
res=tec.Enca(in_c);
tec.InsLug(inom,in_c,iedad,res);
break;
case 5:
cout<<"Que Numero de Control deseas eliminar?"<<endl;
cin>>res;
tec.Borrar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}

ESTRUCTURAS DE DATOS – LECCION 3.3. LISTAS ENLAZADAS Página 26