Sunteți pe pagina 1din 22

CENTRO AMERICANO DE ESTUDIOS SUPERIORES

CARRERA:
INGENIERA EN SISTEMAS COMPUTACIONALES

PROFESOR:
L.I DARO DE LOS NGELES LARA CASTILLO

ASIGNATURA:
ESTRUCTURA DE DATOS I
ALUMNO:
NSTOR DANIEL RODRGUEZ GONZLEZ
TRABAJO:

UNIDAD IV
CUATRIMESTRE:
3

GRUPO:
A

FECHA DE ENTREGA:
08 DE JULIO DEL 2016

Contenido
INTRODUCCIN .................................................................................................................................................................................... 3
Definicin ................................................................................................................................................................................................. 4
Cabecera ficticia y centinela ..................................................................................................................................................................... 4
Listas doblemente enlazadas ..................................................................................................................................................................... 8
Operaciones sobre las listas enlazadas .................................................................................................................................................... 10
PROBLEMAS ........................................................................................................................................................................................ 14
Conclusin .............................................................................................................................................................................................. 21
Bibliografa ............................................................................................................................................................................................. 22

INTRODUCCIN
En el presente trabajo se presenta la estructura de datos listas. Este es un tipo de estructura lineal y dinmica de datos. Lineal porque a
cada elemento le puede seguir solo otro elemento; dinmica porque se puede manejar la memoria de manera flexible, sin necesidad de
reservar espacio con antelacin.
La principal ventaja de manejar un tipo dinmico de datos es que se puede adquirir posicin de memoria a medida que se necesitan;
stas se liberan cuando ya no se requieren. As es posible crear estructuras dinmicas que se expandan o contraigan, segn se les
agregue o elimine elementos. El dinamismo de estas estructuras soluciona el problema de decidir cul es la cantidad ptima de
memoria que se debe reservar para un problema especfico. Sin embargo, es importante destacar que las estructuras dinmicas no
pueden reemplazar a los arreglos en todas sus aplicaciones. Existen numerosos casos que podran facilitarte ser solucionados
aplicando arreglos, mientras que si se utilizan estructuras dinmicas, como las listas, la solucin de estos problemas se complicara.
Las listas ligadas son colecciones de elementos llamados nodos, el orden entre estos se establece por medio de un tipo de datos
denominado punteros, apuntadores, direcciones o referencias a otros nodos. Por tanto, siempre es importante distinguir entre un dato
de tipo apuntador y el dato contenido en la celda al cual este apunta. Se usar la notacin P (^D para indicar que P es un apuntador al
nodo D, Crear (P) para sealar el proceso de asignacin de memoria al nodo P, y Quitar (P) para indicar el proceso inverso; es decir,
cuando se libera una posicin de memoria apuntada por P.
Las operaciones mas importantes que se realizan en las estructuras de datos son las de busqueda, insercion y eliminacion. Se utilizan
tambien para comparar la eficiencia de las estructuras de datos y de esta forma observar cual es la estructura que mejor se adpta al tipo
de problema que se quiere resolver. La busqueda por ejemplo, es una operacin que no se puede realizar en forma eficiente en las
listas. Por otra parte, las operaciones de insercion y eliminacion se efectuan de manera eficiente en este tipo de estructura de datos.
Este capitulo se dedicara a las estructuras dinamicas lineales llamadas listas; entre se distinguen tres tipos: listas simplemente
enlazadas ligadas, listas doblemente ligadas y listas circulares.

Definicin
Las listas enlazadas son estructuras de datos semejantes a los array 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.
En una lista los elementos son contiguos en lo que concierne al enlazado.

En cambio, mientras que en un array los elementos estn contiguos en la memoria, en una lista los elementos
estn dispersos. El enlace entre los elementos se hace mediante un puntero. En realidad, en la memoria la
representacin es aleatoria en funcin del espacio asignado.
El puntero siguiente del ltimo elemento tiene que apuntar hacia NULL (el fin de la lista).
Para acceder a un elemento, la lista es recorrida comenzando por el inicio, el puntero Siguientepermite el
cambio hacia el prximo elemento.
El desplazamiento se hace en una sola direccin, del primer al ltimo elemento.
Si deseas desplazarte en las dos direcciones (hacia delante y hacia atrs) debers utilizar las listas doblemente
enlazadas.

Cabecera ficticia y centinela


Como se ha observado anteriormente, a la hora de insertar o actualizar elementos en una lista ordenada o
reorganizarle es fundamental actualizar el primer elemento de la lista cuando sea necesario. Esto lleva un
coste de tiempo, aunque sea pequeo salvo en el caso de numerosas inserciones y borrados. Para subsanar
este problema se utiliza la cabecera ficticia.
La cabecera ficticia aade un elemento (sin clave, por eso es ficticia) a la estructura delante del primer
elemento. Evitar el caso especial de insertar delante del primer elemento. Grficamente se puede ver as:

Se declara una lista vaca con cabecera, reservando memoria para la cabecera, de la siguiente manera:
struct lista {
int clave;
struct lista *sig;
}
...
struct lista *L;
L = (struct lista *) malloc(sizeof(struct lista));
L->sig = NULL;

Antes de implementar el proceso de insercin en una lista con cabecera, se explicar el uso del centinela, y se
realizarn los procedimientos de insercin y borrado aprovechando ambas ideas.
El centinela es un elemento que se aade al final de la estructura, y sirve para acotar los elementos de
informacin que forman la lista. Pero tiene otra utilidad: el lector habr observado que a la hora de buscar un
elemento de informacin, ya sea en la insercin o en el borrado, es importante no dar un paso en falso, y por
eso se comprueba que no se est en una posicin de informacin vaca. Pues bien, el centinela evita ese
problema, al tiempo que acelera la bsqueda.
A la hora de la bsqueda primero se copia la clave que buscamos en el centinela, y a continuacin se hace una
bsqueda por toda la lista hasta encontrar el elemento que se busca. Dicho elemento se encontrar en
cualquier posicin de la lista, o bien en el centinela en el caso de que no estuviera en la lista. Como se sabe
que el elemento est en algn lugar de la lista (aunque sea en el centinela) no hay necesidad de comprobar si
estamos en una posicin vaca.
Cuando la lista est vaca la cabecera apunta al centinela. El centinela siempre se apunta a si mismo. Esto se
hace as por convenio.
Grficamente se puede representar as:

A continuacin se realiza una implementacin de lista enlazada ordenada, que incluye a la vez cabecera y
centinela.
struct lista
{
int clave;
struct lista *sig;
};
/* lista con cabecera y centinela */
struct listacc

{
struct lista *cabecera,
*centinela;
};
Procedimiento de inicializacin (ntese el *LCC):
void crearLCC(struct listacc *LCC)
{
LCC->cabecera = (struct lista *) malloc(sizeof(struct lista));
LCC->centinela = (struct lista *) malloc(sizeof(struct lista));
LCC->cabecera->sig = LCC->centinela;
LCC->centinela->sig = LCC->centinela; /* opcional, por convenio */
}
Procedimiento de insercin:
void insertarLCC(struct listacc LCC, int elem)
{
struct lista *anterior, *actual, *nuevo;
/* 1.- busca */
anterior = LCC.cabecera;
actual = LCC.cabecera->sig;
LCC.centinela->clave = elem;
while (actual->clave < elem) {
anterior = actual;
actual = actual->sig;
}
/* 2.- crea */
nuevo = (struct lista *) malloc(sizeof(struct lista));
nuevo->clave = elem;
/* 3.- enlaza */
nuevo->sig = actual;
anterior->sig = nuevo;
}
Procedimiento de borrado:
void borrarLCC(struct listacc LCC, int elem)
{
struct lista *anterior, *actual;
/* 1.- busca */
anterior = LCC.cabecera;
actual = LCC.cabecera->sig;
LCC.centinela->clave = elem;
while (actual->clave < elem) {
anterior = actual;

actual = actual->sig;
}
/* 2.- borra si existe */
if (actual != LCC.centinela && actual->clave == elem) {
anterior->sig = actual->sig;
free(actual);
}
}
Ejemplo de uso:
#include <stdio.h>
#include <stdlib.h>
struct lista
{
int clave;
struct lista *sig;
};
struct listacc
{
struct lista *cabecera,
*centinela;
};
void crearLCC(struct listacc *LCC);
void insertarLCC(struct listacc LCC, int elem);
void borrarLCC(struct listacc LCC, int elem);
int main(void)
{
struct listacc LCC;
crearLCC(&LCC);
insertarLCC(LCC, 3);
borrarLCC(LCC, 3);
return 0;
}
La realizacin de la lista reorganizable aprovechando la cabecera y el centinela se deja propuesta como
ejercicio.

Listas doblemente enlazadas


Son listas que tienen un enlace con el elemento siguiente y con el anterior. Una ventaja que tienen es que
pueden recorrerse en ambos sentidos, ya sea para efectuar una operacin con cada elemento o para
insertar/actualizar y borrar. La otra ventaja es que las bsquedas son algo ms rpidas puesto que no hace
falta hacer referencia al elemento anterior. Su inconveniente es que ocupan ms memoria por nodo que una
lista simple.
Se realizar una implementacin de lista ordenada con doble enlace que aproveche el uso de la cabecera y el
centinela. A continuacin se muestra un grfico que muestra una lista doblemente enlazada con cabecera y
centinela, para lo que se utiliza un nico nodo que haga las veces de cabecera y centinela.

- Declaracin:
struct listaDE
{
int clave;
struct listaDE *ant,
*sig;
};
- Procedimiento de creacin:
void crearDE(struct listaDE **LDE)
{
*LDE = (struct listaDE *) malloc(sizeof(struct listaDE));
(*LDE)->sig = (*LDE)->ant = *LDE;
}
- Procedimiento de insercin:
void insertarDE(struct listaDE *LDE, int elem)
{
struct listaDE *actual, *nuevo;
/* busca */
actual = LDE->sig;
LDE->clave = elem;

while (actual->clave < elem)


actual = actual->sig;
/* crea */
nuevo = (struct listaDE *) malloc(sizeof(struct listaDE));
nuevo->clave = elem;
/* enlaza */
actual->ant->sig = nuevo;
nuevo->ant = actual->ant;
nuevo->sig = actual;
actual->ant = nuevo;
}
- Procedimiento de borrado:
void borrarDE(struct listaDE *LDE, int elem)
{
struct listaDE *actual;
/* busca */
actual = LDE->sig;
LDE->clave = elem;
while (actual->clave < elem)
actual = actual->sig;
/* borra */
if (actual != LDE && actual->clave == elem) {
actual->sig->ant = actual->ant;
actual->ant->sig = actual->sig;
free(actual);
}
}
Para probarlo se pueden usar las siguientes instrucciones:
struct listaDE *LDE;
...
crearDE(&LDE);
insertarDE(LDE, 1);
borrarDE(LDE, 1);

Operaciones sobre las listas enlazadas


Para la insercin y la eliminacin, una nica funcin bastar si est bien concebida de acuerdo a lo que
se necesite. Debo recordar que este artculo es puramente didctico. Por lo tanto, he escrito una funcin
para cada operacin de insercin y eliminacin.

Inicializacin
Modelo de la funcin:

void inicializacion (Lista *lista);

Esta operacin debe ser hecha antes de otra operacin sobre la lista.
Esta comienza el puntero inicio y el puntero fin con el puntero NULL, y el tamao con el valor 0.
La funcin

void inicializacion (Lista *lista){


lista->inicio = NULL;
lista->fin = NULL;
tamao = 0;
}

Insercin de un elemento en la lista


A continuacin el algoritmo de insercin y el registro de los elementos: declaracin del elemento que se
va a insertar, asignacin de la memoria para el nuevo elemento, llena el contenido del campo de datos,
actualizacin de los punteros hacia el primer y ltimo elemento si es necesario. Caso particular: en una
lista con un nico elemento, el primero es al mismo tiempo el ltimo. Actualizar el tamao de la lista
Para aadir un elemento a la lista hay varios casos: insercin en una lista vaca, insercin al inicio de la
lista, insercin al final de la lista e insercin en otra parte de la lista.

Insercin en una lista vaca


Ejemplo de la funcin:

int ins_en_lista_vacia (Lista *lista, char *dato);

La funcin retorna 1 en caso de error, si no devuelve 0.

Las etapas son asignar memoria para el nuevo elemento, completa el campo de datos de ese nuevo
elemento, el puntero siguiente de este nuevo elemento apuntar hacia NULL (ya que la insercin es
realizada en una lista vaca, se utiliza la direccin del puntero inicio que vale NULL), los
punteros inicio y fin apuntaran hacia el nuevo elemento y el tamao es actualizado

La funcin

/* insercin en una lista vaca */


int ins_en_lista_vacia (Lista * lista, char *dato){
Element *nuevo_elemento;
if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
return -1;
if ((nuevo _elemento->dato = (char *) malloc (50 * sizeof (char)))
== NULL)
return -1;
strcpy (nuevo_elemento->dato, dato);
nuevo_elemento->siguiente = NULL;
lista->inicio = nuevo_elemento;
lista->fin = nuevo_elemento;
lista->tamao++;
return 0;
}

Insercin al inicio de la lista


Ejemplo de la funcin:

int ins_inicio_lista (Lista *lista,char *dato);

La funcin da -1 en caso de error, de lo contrario da 0.


Etapas: asignar memoria al nuevo elemento, rellenar el campo de datos de este nuevo elemento, el
puntero siguiente del nuevo elemento apunta hacia el primer elemento, el puntero inicioapunta al nuevo
elemento, el puntero fin no cambia, el tamao es incrementado

La funcin

/* insercin al inicio de la lista */


int ins_inicio_lista (Lista * lista, char *dato){
Element *nuevo_elemento;
if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
return -1;
if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
== NULL)
return -1;
strcpy (nuevo_elemento->dato, dato);
nuevo_elemento->siguiente = lista->inicio
lista->inicio = nuevo_elemento;
lista->tamao++;
return 0;
}

Insercin al final de la lista


Ejemplo de la funcin:

int ins_fin_lista (Lista *lista, Element *actual, char *dato);

La funcin da -1 en caso de error, si no arroja 0.


Etapas: proporcionar memoria al nuevo elemento, rellenar el campo de datos del nuevo elemento, el
puntero siguiente del ultimo elemento apunta hacia el nuevo elemento, el punterofin apunta al nuevo
elemento, el puntero inicio no vara, el tamao es incrementado:

La funcin

/*insercin al final de la lista */


int ins_fin_lista (Lista * lista, Element * actual, char *dato){
Element *nuevo_elemento;
if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
return -1;
if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
== NULL)
return -1;
strcpy (nuevo_elemento->dato, dato);
actual->siguiente = nuevo_elemento;
nuevo_elemento->siguiente = NULL;
lista->fin = nuevo_elemento;
lista->tamao++;
return 0;
}

PROBLEMAS
Crear una lista que almacene los "n" primeros nmeros
mayor y el promedio.
#include <iostream>
#include <stdlib.h>
using namespace std;
struct nodo{
int nro;
struct nodo *sgte;
};

typedef struct nodo *Tlista;

/*-------------------- Insertar siguiente Elemento-------------------------*/


void insertarSgte(Tlista &lista, int valor)
{
Tlista t, q = new(struct nodo);
q->nro = valor;
q->sgte = NULL;
if(lista==NULL)
{
lista = q;
}
else
{
t = lista;
while(t->sgte!=NULL)
{
t = t->sgte;
}
t->sgte = q;
}
}
/*----------------------Mostrar Lista--------------------------------------*/
void reportarLista(Tlista lista)
{

enteros y calcular el menor,

int i = 0;
while(lista != NULL)
{
cout <<' '<< i+1 <<") " << lista->nro << endl;
lista = lista->sgte;
i++;
}
}

void calcularMayMenProm(Tlista lista, int mayor, int menor, int promedio, int n){
while(lista!=NULL){
if(mayor<(lista->nro))
mayor=lista->nro;
if(menor>(lista->nro))
menor=lista->nro;
promedio+=lista->nro;
lista=lista->sgte;
}
promedio=promedio/n;
cout<<endl<<"mayor:"<<mayor<<endl;
cout<<endl<<"menor:"<<menor<<endl;
cout<<endl<<"promedio:"<<promedio<<endl<<endl;
}
/*------------------------- Funcion Principal ---------------------------*/
int main(void)
{
Tlista lista = NULL;
system("color 0a");
cout<<"\n\n\t\t[ EJERCICIOS LISTAS SIMPLES ]\n";
cout<<"\t\t-----------------------------\n\n";
cout<<" EJERCICIO 1: Calcular mayor,menor y promedio de una lista"<<endl<<endl;

cout<<"\n Ingrese tamanio de lista: ";


cin>>n;
for(int i=1;i<=n;i++){
insertarSgte(lista,i);
}
cout<<endl<<"Elementos de lista"<<endl;
reportarLista(lista);
mayor=lista->nro;
menor=lista->nro;
promedio=lista->nro;
lista=lista->sgte;
calcularMayMenProm(lista, mayor, menor, promedio, n);

system("pause");
return 0;
}

Almacenar nmeros reales en una lista y Reportarlos en forma ordenada.


#include <iostream>
#include <stdlib.h>
using namespace std;
struct nodo{
float nro;
struct nodo *sgte;
};
typedef struct nodo *Tlista;
Tlista fin;
/*------------------Menu----------------------------------*/
void menu1()
{
cout<<"\n\n\t\t[ EJERCICIOS LISTAS SIMPLES ]\n";
cout<<"\t\t-----------------------------\n\n";

cout<<" EJERCICIO 2: Almacenar una lista de reales y ordenarlos"<<endl<<endl;


cout<<" 1. INSERTAR ELEMENTO
cout<<" 2. MOSTRAR LISTA ORDENADA
cout<<" 3. SALIR

"<<endl;
"<<endl;

"<<endl;

cout<<"\n INGRESE OPCION: ";


}
/*----------------------------insertar elemento al inicio ---------------------*/
void insertarInicio(Tlista &lista, float valor)
{
Tlista q;
q = new(struct nodo);
q->nro = valor;
q->sgte = lista;
lista = q;
}
/*-------------------- Insertar siguiente Elemento-------------------------*/
void insertarFinal(Tlista &lista, float valor)
{
Tlista t, q = new(struct nodo);
q->nro = valor;
q->sgte = NULL;
fin=q;
if(lista==NULL)
{
lista = q;
}
else
{
t = lista;
while(t->sgte!=NULL)
{
t = t->sgte;
}

t->sgte = q;
}
}
/*------------------------- Funcio que inserta el elemento ordenado antes del mayor y despues del menor*/
void insertarElementoEn(Tlista lista, float n){
Tlista t,r,q=new (struct nodo);
q->nro=n;
q->sgte=NULL;
while(lista->sgte!=NULL){
t=lista->sgte;
if((n>=(lista->nro))&&(n<=t->nro)){
q->sgte=lista->sgte;
lista->sgte=q;
return;
}
lista=lista->sgte;
}
}
/*----------------------Mostrar Lista--------------------------------------*/
void reportarLista(Tlista lista)
{
int i = 0;
while(lista != NULL)
{
cout <<' '<< i+1 <<") " << lista->nro << endl;
lista = lista->sgte;
i++;
}
}

/*------------------------- Funcion Principal ---------------------------*/


int main(void)
{
Tlista lista = NULL;
int op;
float n;
system("color 0a");
do
{
menu1(); cin>> op;
switch(op)
{
case 1:
cout<< "\n NUMERO A INSERTAR: "; cin>> n;
if(lista==NULL){
insertarFinal(lista,n);
}
else{
if(n<lista->nro)
insertarInicio(lista,n);
else if(n>fin->nro)
insertarFinal(lista,n);
else{ if((n>lista->nro)&&(n<fin->nro)){
insertarElementoEn(lista,n);
}
}

}
break;

case 2:
cout<<endl<<"La lista Ordenada es:"<<endl;
reportarLista(lista);
break;
case 3: return 0;
default: cout<<"Ingrese una Opcion Valida....!"<<endl;

cout<<endl<<endl;
system("pause"); system("cls");

}while(op!=3);

system("pause");
return 0;
}

Conclusin
Las listas enlazadas son muy verstiles. Adems, pueden definirse
estructuras ms complejas a partir de las listas, como por ejemplo arrays
de listas, etc.
En algunas ocasiones los grafos se definen como listas de adyacencia (ver
seccin de grafos). Tambin se utilizan para las tablas de hash (dispersin)
como arrays de listas.
Son eficaces igualmente para disear colas de prioridad, pilas y colas sin
prioridad, y en general cualquier estructura cuyo acceso a sus elementos
se realice de manera secuencial.

Bibliografa
Annimo. (21 de julio de 2008). La lista enlazada simple. Recuperado el 07 de Julio de 2016, de ccm: es..net/faq/2842-la-listaenlazada-simple#operaciones-sobre-las-listas-enlazadas
Dimeisons, N. (29 de julio de 2014). Monografias.com . Recuperado el 07 de Julio de 2016, de Listas Enlazadas:
http://www.monografias.com/trabajos101/las-istas-enlazadas/las-istas-enlazadas.shtml
Fernandez, J. (14 de octubre de 2014). Codebotic. Recuperado el 07 de julio de 2016, de Ejercicios Con Listas Enlazadas Simples En
C++: http://www.codebotic.com/2014/10/ejercicios-con-listas-enlazadas-simples.html

S-ar putea să vă placă și