Vous êtes sur la page 1sur 16

Estructuras Dinmicas de datos.

Las estructuras dinmicas de datos son estructuras que crecen a medida que
ejecuta un programa. Una estructura dinmica de datos es una coleccin de
elementos llamadas nodos - que son normalmente registros. Al contrario de
un arreglo que contiene espacio para almacenar un nmero fijo de elementos,
una estructura dinmica de datos se ampla y contrae durante la ejecucin del
programa, basada en los registros de almacenamiento de datos del programa.
Las estructuras dinmicas de datos se pueden dividir en dos grandes grupos:

Lineales
Pilas.
Colas.

Listas enlazadas.
No lineales
rboles.
Grafos.

Las estructuras dinmicas de datos se utilizan para almacenamiento de datos
del mundo real, que estn cambiando constantemente. Un ejemplo tpico, es la
lista de pasajeros de una lnea area. Si esta lista se mantuviera en orden
alfabtico en un arreglo, sera necesario hacer espacio para insertar un nuevo
pasajero por orden alfabtico. Esto requiere utilizar un ciclo para copiar los
datos del registro de cada pasajero al siguiente elemento del arreglo. Si en su
lugar se utilizar una estructura dinmica de datos, los nuevos datos del
pasajero se pueden insertar simplemente entre dos registros existentes con un
mnimo de esfuerzo.
Listas.
Una lista lineal es un conjunto de elementos de un tipo dado que se encuentran
ordenados y pueden variar en nmero.
Los elementos de una lista lineal se almacenan normalmente contiguos en
posiciones consecutivas de la memoria. Las sucesivas entradas en una gua o
directorio telefnico, por ejemplo, estn en lneas sucesivas, excepto en las
partes superior e inferior de cada columna. Una lista lineal se almacena en la
memoria principal de una computadora en posiciones sucesivas de memoria;
cuando se almacenan en cinta magntica, los elementos sucesivos se
presentan en sucesin en la cinta. Esta sucesin se denomina almacenamiento
secuencial.
Las lneas as definidas se denominan contiguas. Las operaciones que se
pueden realizar con listas lineales contiguas son:

1. Insertar, eliminar o localizar un elemento.
2. Determinar el tamao de la lista (nmero de elementos).
3. Recorrer la lista para localizar un determinado elemento.
4. Clasificar los elementos de la lista en orden ascendente o descendente.
5. Unir dos o ms listas en una sola.
6. Dividir una lista en varias sublistas.
7. Copiar una lista.
8. Borrar una lista
Una lista lineal se almacena en la memoria de la computadora en posiciones
sucesivas o adyacentes y se procesa como un arreglo unidimensional. En este
caso, el acceso a cualquier elemento de la lista y la adicin de nuevos
elementos es fcil; Sin embargo la insercin o borrado requiere un
desplazamiento de lugar de los elementos que le siguen y, en consecuencia un
diseo de algoritmo especifico.

Listas encaden
Una lista enlazada o encadenada es un conjunto de elementos en los que cada
elemento contiene la
posicin o direccin del siguiente elemento de la lista. Cada elemento de la lista
encadenada debe tener al menos dos campos: Un campo que tiene el valor del
elemento y un campo (enlace o link) que contiene la posicin del siguiente
elemento, es decir, su conexin, enlace o encadenamiento. Los elementos de
una lista son enlazados por medio de los campos enlaces.
Las listas encadenadas tienen una terminologa propia que se suele utilizar
normalmente. Primero, los valores se almacenan en un nodo.
Los componentes de un nodo se llaman campos. Un nodo tiene al menos un
campo de dato o valor y un enlace (indicador o puntero) con el siguiente
campo. El campo enlace apunta (proporciona la direccin de) al siguiente nodo
de la lista. El ltimo nodo de la lista encadenada, por convenio, se suele
representar por un enlace con la palabra nil (nulo), una barra inclinada, y en
ocasiones, el smbolo elctrico de tierra o masa.
Una lista enlazada o encadenada es una lista que se construye empleando
apuntadores. Adems, no tiene un tamao fijo, sino que puede crecer y
decrecer durante la ejecucin del programa. Se constituyen como variables
dinmicas.
En las listas enlazadas no es necesario que los elementos en la lista sean
almacenados en posiciones fsicas adyacentes, ya que el apuntador indica
dnde se encuentra el siguiente elemento de la lista.
Por consiguiente, la insercin y borrado no exigen desplazamiento al como en
el caso de las listas contiguas.
Para eliminar un elemento de una lista enlazada, solo es necesario cambiar el
puntero del elemento anterior al elemento siguiente del que deseamos eliminar.
Para insertar un elemento en determinada posicin, solo necesitamos cambiar
el apuntador de la posicin anterior a donde queremos insertar a nuestro nuevo
elemento y este elemento deber direccionar el elemento al que anteriormente
apuntaba el elemento que quedo antes del nuevo elemento.
Una lista enlazada sin ningn elemento se llama lista vaca. Su puntero inicial o
de cabecera tiene el valor nulo (nil).
Una lista enlazada se puede definir por:
El tipo de sus elementos: campo de informacin (datos) y campo enlace
(puntero).
Un puntero de cabecera que permite acceder al primer elemento de la lista.
Un medio para detectar el ltimo elemento de la lista: puntero nulo (nil).

Las operaciones que hay que realizar con una lista enlazada son:
1. Definir y crear los nodos.
2. Definir la cabecera (o inicio) de la lista.
3. Recorrer los nodos de una lista enlazada.
4. Agregar un nodo a la lista.
a. Al final.
b. Al Principio.
c. En el centro.
5. Eliminar un nodo de la lista.
a. Al final.
b. Al Principio.
c. En el centro. Pilas
Es una estructura de datos especial en donde la insercin y el borrado de los
nuevos elementos se realizan slo por un extremo que se denomina cima o
tope. Esta estructura posee numerosas analogas en la vida real, por ejemplo
imagine una pila de platos.
Dado que las operaciones de insertar y eliminar se realizan por un solo extremo
(el superior), los elementos solo pueden eliminarse en orden inverso al que se
insertan en la pila. El ltimo elemento que se pone en la pila es el primero en
sacar; dado a esto a estas estructuras se les conoce con el nombre de LIFO.
Las operaciones que se pueden realizar con una pila son:
PUSH (pila, elemento): Introduce un elemento en la pila. Tambin se le conoce
como poner o meter.
POP (pila): Elimina un elemento de la pila. Tambien se le conoce como sacar o
quitar.
VACIA(pila): Funcin booleana que indica si la pila esta vacia o no.
Las pilas se pueden implementar por arreglos o bien por punteros siempre y
cuando se respete el concepto antes mencionado.
Idealmente, una pila puede contener un nmero ilimitado de elementos y no
producir nunca desbordamiento. En la prctica, sin embargo, el espacio de
almacenamiento disponible es finito. La codificacin de una pila requiere un
cierto equilibrio, ya que si la longitud mxima es demasiado grande, se gasta
mucha memoria, mientras que un valor pequeo de longitud maxima producira
despordamientos frecuentes.
Colas (filas)
Las colas o filas son otro tipo de estructura lineal de datos, similares a las pilas,
diferencindose de ellas en el modo de insertar eliminar elementos.
Una cola es una estructura lineal de datos en la que las eliminaciones se
realizan al principio de la lista, y las inserciones se realizan por el fina de la
misma. En las colas el elemento que entr primero tambin sale primero, por
ello se conocen como estructuras FIFO. As pues la diferencia con las pilas es
solamente el modo de entrada y salida de datos.
En la vida real se tienen ejemplos numerosos de colas: la cola de un autobs,
la cola de un cine, etc. En 5. Verificar el estado de la colae todas ellas el primer
elemento que llega es el primero que sale.
En informtica existen tambin numerosas aplicaciones de colas. Por ejemplo,
en un sistema de tiempo compartido suele haber un procesador central y una
serie de perifricos compartidos: discos, impresoras, etc. Los recursos se
comparten por los diferentes usuarios y se utiliza una cola para almacenar los
programas o peticiones de los usuarios que esperan su turno.
Las colas se pueden representar como estructuras dinmicas de datos o como
arreglos.
Las operaciones que se pueden realizar con una cola son:
1. Acceder al primer elemento de la cola.
2. Aadir un elemento al final de la cola.
3. Eliminar el primer elemento de la cola.
4. Vaciar la cola.

Punteros
Hemos visto ya cmo las variables son las clulas de memoria a las que podemos tener
acceso por un identificador. Pero estas variables se guardan en lugares concretos de la
memoria de la computadora. Para nuestros programas, la memoria de la
computadora es solamente una sucesin de las clulas de 1 octeto (la talla mnima para
un dato), cada una con una direccin nica.
La memoria de computadora puede ser comparada con una calle en una ciudad. En
una calle todas las casas se numeran consecutivamente con un identificador nico tal
que si hablamos del nmero 27 de la calle Crdova, podremos encontrar el lugar sin
prdida, puesto que debe haber solamente una casa con ese nmero y, adems,
nosotros sabemos que la casa estar entre las casas 26 y 28.
Una declaracin de puntero consiste en un tipo base, un * y el nombre de la variable.
La forma general de declaracin de una variable puntero es:
Tipo *nomb_var;
Donde:
Tipo: cualquier tipo valido ,ya sea primitivo o definido por el usuario
nomb_var: es el nombre de la variable de tipo apuntador.
Los operadores de punteros
Existen dos operadores especiales de punteros: & y *.
El & devuelve la direccin de memoria de su operando. Por ejemplo:
m=&cuenta;
pone en m la direccin de memoria de la variable cuenta. Esta direccin es la posicin
interna de la variable en la computadora. La direccin no tiene nada que ver con
el valor de cuenta. Se puede pensar en el operador & como devolviendo "la direccin
de".
El segundo operador de punteros, *, es el complemento de &. Devuelve el valor de la
variable localizada en la direccin que sigue. Por ejemplo, si m contiene la direccin de
memoria de la variable cuenta, entonces:
q=*m;
pone el valor de cuenta en q. Se puede pensar en * como "en la direccin".
El siguiente programa ilustra un ejemplo:
#include <stdio.h>
main()
{int cuenta, q;
int *m;
cuenta=100;
m=&cuenta; //m recibe la direccin de cuenta
q=*m; //a q se le asigna el valor de cuenta
indirectamente a travs de m
print("%d,q") //imprime 100
}
Punteros estticos
Definamos un puntero a un entero y una variable entera como sigue:
Int *p1;
Int valor1;
Con estas definiciones es posible hacer las siguientes asignaciones estticas:
p1= *valor1;
*p1=25;
El apuntador p1 se define como un apuntador a un entero. La variable valor2 se define
como una variable entera. La primera asignacin hace que p1 apunte a la variable
valor1, la segunda asignacin almacena en memoria el valor 25 en donde p1 est
apuntando.
Se dice que este tipo de inicializacin es de tipo esttica porque la asignacin de la
memoria que se utiliza para almacenar es fija. Una vez definida la variable, el
compilador establece suficiente memoria para almacenar un valor de un tipo dado. Esta
memoria permanece reservada para esta variable y no es posible usarla para nada ms
hasta que se termine la funcin.
Punteros Dinmicos
La segunda forma para inicializar un puntero es por medio de la asignacin dinmica de
memoria. Por asignacin dinmica de la memoria se entiende que se reserva memoria
cuando se necesite para almacenar un valor de un tipo dado. Despus, una vez que no
se necesite el valor, es posible liberar la memoria y hacerla disponible para otro uso por
el sistema .
De nuevo definamos a p1 como un valor entero como sigue:
Int *p1;
Ahora es posible inicializar a p1 en forma dinmica para apuntar a un valor de la
siguiente manera:
p1=new int;
*p1=25;
Esta vez no es necesario inicializar primero p1 a la direccin de un a variable esttica.
En cambio el operador new crea suficiente memoria para contener un valor entero
apuntado por p1. Despus se almacena en esta rea de memoria el valor 25. Una vez
que se asigna dinmicamente la memoria como sta, es posible liberar la misma rea
de memoria usando el operador delete, como sigue:
Delete p1;
Esta operacin liberar la memoria apuntada por p1.
Es importante sealar que el operador delete no elimina el apuntador, simplemente
libera el rea de memoria al cual se dirige el puntero. Por tanto luego que se ejecute el
enunciado anterior, p1 todava existe como un puntero que no apunta a nada, pero que
es posible inicializarlo de nuevo para apuntar a otro entero utilizando el operador new.
2. Estructuras dinmicas
Las estructuras dinmicas de datos son estructuras que cuya dimensin puede crecer o
disminuir durante la ejecucin del programa. Una estructuradinmica de datos es una
coleccin de elementos llamados nodos. Al contrario que un array, que contiene
espacio para almacenar un nmero fijo de elementos, una estructura dinmica de datos
se ampla y contrae durante la ejecucin del programa.
Las estructuras dinmicas de datos se pueden dividir en dos grandes grupos:
Lineales: listas enlazadas, pilas, colas
No lineales: rboles , grafos
Las estructuras dinmicas de datos son de gran utilidad para almacenar datos del
mundo real, que estn cambiando constantemente. Por ejemplo si tenemos
almacenados en un array los datos de los alumnos de un curso, los cuales estan
ordenados de acuerdo al promedio, para insertar un nuevo alumno seria necesario
correr cada elemento un espacio: Si en su lugar se utilizara una estructura dinmica de
datos, los nuevos datos del alumno se pueden insertar fcilmente.
3. Listas
Listas Enlazadas
Una lista enlazada es un conjunto de elementos llamados nodos en los que cada uno
de ellos contiene un dato y tambin la direccin del siguiente nodo.
El primer elemento de la lista es la cabecera, que slo contiene un puntero que seala
el primer elemento de la lista.
El ltimo nodo de la lista apunta a NULL (nulo) porque no hay ms nodos en la lista. Se
usar el trmino NULL para designar el final de la lista.
La lista enlazada se muestra en la siguiente figura:
Cabecera
Las operaciones que normalmente se ejecutan con listas incluyen:
1. Recuperar informacin de un nodo especfico.
2. Encontrar el nodo que contiene una informacin especfica.
3. Insertar un nuevo nodo en un lugar especfico.
4. Insertar un nuevo nodo en relacin a una informacin particular.
5. Borrar un nodo existente.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
class nodo
{int num;
nodo *sgte;
public:
nodo(){sgte=NULL;}
void apns(nodo *n);
nodo *rpns();
void ingresar();
int mostrar();
};
void nodo::apns(nodo *n)
{sgte=n;}
nodo *nodo::rpns()
{return sgte;}
void nodo::ingresar()
{cin>>num;}
int nodo::mostrar()
{return num;}
/////////////////////////////////////////
class lista
{nodo *cab;
public:
lista(){cab=NULL;}
void insertar_i();
void insertar_f();
void eliminar_nodo();
void mostrar_lista();
void eliminar_i();
void eliminar_f();
void eliminar_lista();
};
void lista::insertar_f()
{nodo *a;
a=new nodo;
a->ingresar();
if(cab==NULL)
{cab=a;}
else
{nodo *temp,*temp1,*temp2;
temp=cab;
while(temp2!=NULL)
{temp1=temp->rpns();
temp2=temp1->rpns();}
temp->rpns();
temp->apns(a);
}
}
void lista::insertar_i()
{nodo *a;
a=new nodo;
a->ingresar();
if(cab==NULL)
cab=a;
else
{nodo *temp;
temp=cab;
cab=a;
cab->apns(temp);
}
}
void lista::mostrar_lista()
{nodo *t;
if (cab==NULL)
cout<<"La lista esta vacia";
else
{t=cab;
while(t!=NULL)
{//t=t->rpns();
cout<<t->mostrar();
t=t->rpns();
}
}
}
void lista::eliminar_nodo()
{nodo *temp,*temp1,*temp2;
temp1=cab;
int numero;
cout<<"ingrese numero a borrar";
cin>>numero;
if(temp1->rpns()==NULL)
cout<<"no hay elementos";
else
{do
{temp=temp1;
temp1=temp1->rpns();
if(temp1->mostrar()==numero)
{temp2=temp1->rpns();
temp->apns(temp2);
delete temp1;
}
}while(temp!=NULL); /////
}}
void lista::eliminar_i()
{if(cab==NULL)
cout<<"\nno existen nodos";
else
{nodo *temp;
temp=cab;
cab=cab->rpns();
delete temp;
}
}
void lista::eliminar_f()
{if(cab==NULL)
cout<<"\nno existen nodos";
else
{nodo *ptr1, *ptr2;
ptr2=cab;
ptr1=NULL;
while(ptr2->rpns()!=NULL)
{ptr1=ptr2;
ptr2=ptr2->rpns();
}
if(ptr1==NULL)
{delete cab;
cab=NULL;
}
else
{delete ptr2;
ptr1->apns(NULL);
}
}
}}
void lista::eliminar_lista()
{nodo *temp;
while(cab!=NULL)
{temp=cab;
cab=cab->rpns();
delete temp;
}
}
void main()
{int op;
lista b;
clrscr();
for(;;)
{
cout<<"\n\n<1> insertar al inicio";
cout<<"\n<2> insertar al final";
cout<<"\n<3> eliminar nodo";
cout<<"\n<4> mostrar lista";
cout<<"\n<5> eliminar inicio";
cout<<"\n<6> eliminar final";
cout<<"\n<7> eliminar lista";
cout<<"\n<8> salir\n";
op=getch();
switch(op)
{case '1': b.insertar_i();break;
case '2': b.insertar_f();break;
case '3': b.eliminar_nodo(); break;
case '4': b.mostrar_lista();break;
case '5': b.eliminar_i();break;
case '7': b.eliminar_lista();break;
case '8': exit(0);
}
}
}
Listas Doblemente Enlazadas
Hasta ahora se han manejado listas que se recorren en un asola direccin. En algunas
aplicaciones es prctico o hasta indispensable poder recorrer una lista en ambas
direcciones. Para estos casos se tienen las lista doblemente enlazadas.
Esta propiedad implica que cada nodo debe tener dos apuntadores, uno al nodo
predecesor y otro al nodo sucesor.
Cabecera
Listas Circulares
Una lista circular es una lista en la cual el ltimo nodo es enlazado al primer elemento
de la lista. La ventaja de este tipo de estructura es que siempre se puede llegar a
cualquier nodo siguiendo los enlaces. La desventaja es que si no se tiene cuidado una
bsqueda puede resultar en un bucle infinito. Esto se puede evitar al determinar a un
nodo como nodo-cabeza o nodo inicial.
Pilas
Una pila es un tipo especial de lista lineal en la cual un elemento slo puede ser
aadido o eliminado por un extremo llamado cima. Esto significa que los elementos se
sacan de la pila en orden inverso al que se pusieron en ella.
Las dos operaciones bsicas asociadas a las pilas son:
-Poner: es aadir un elemento a la pila.
-Sacar: es extraer un elemento de la pila.
La pila es una estructura con numerosas analogas en la vida real: una pila de platos,
una pila de monedas, una pila de bandejas, etc.
La representacin consiste en un vector con espacio para un mximo de elementos y
un contador que indica el nmero de elementos vlidos almacenados en el vector.
Colas
Una cola es una lista en las que las supresiones se realizan solamente solamente al
principio de la lista y las inserciones al final de la misma. Al igual que en el caso de las
pilas, hay que prever un vector para almacenar el mximo nmero de elementos que
puedan presentarse en el programa. A diferencia de las pilas, no basta con aadir un
simple contador, tal que indique el nmero de elementos vlidos; sino hay que prever
dos ndices que indiquen la posicin del comienzo y del final de la cola. Si la cola no
est vaca, en CABEZA est el primer elemento, y si la cola no est llena, en FIN es el
lugar donde se copia el siguiente elemento que se incorpora a la misma.
Las colas se usan para almacenar datos que necesitan ser procesados segn el orden
de llegada. En la vida real se tienen ejemplos numerosos de colas: la cola de un cine, la
cola de un banco, etc; en todas ellas el primer elemento que llega es el primero que
sale