Professional Documents
Culture Documents
Una de las aplicaciones ms interesantes y potentes de la memoria dinmica y los punteros son las estructuras dinmicas de datos. Las estructuras bsicas disponibles en C y C++ tienen una importante limitacin: no pueden cambiar de tamao durante la ejecucin. Los arreglos estn compuestos por un determinado nmero de elementos, nmero que se decide en la fase de diseo, antes de que el programa ejecutable sea creado. En muchas ocasiones se necesitan estructuras que puedan cambiar de tamao durante la ejecucin del programa. Por supuesto, podemos hacer 'arrays' dinmicos, pero una vez creados, tu tamao tambin ser fijo, y para hacer que crezcan o diminuyan de tamao, deberemos reconstruirlas desde el principio, por este motivo los arrays no hacen un uso eficiente de la memoria.
OBJETIVOS
1. Entender la eficacia del manejo de la memoria dinmica a travs del uso de apuntadores 2. Lograr un uso eficiente de las estructuras de datos lineales.
Punteros o apuntadores
Las variables vistas hasta este momento contienen valores de datos, por el contrario las variables punteros contienen valores que son direcciones de memoria donde se almacenan datos. En resumen, un puntero es una variable que contiene una direccin de memoria, y utilizando punteros su programa puede realizar muchas tareas que no sera posible utilizando tipos de datos estndar.
Cuando se telefonea a una persona, se utiliza un puntero (el nmero de telfono que se marca).
As pues, una direccin de correos y un nmero de telfono tienen en comn que ambos indican dnde encontrar algo.
Los punteros tienen una gran utilidad, pues permiten una programacin eficaz a nivel de mquina cuando se maneja la memoria del ordenador. Permiten realizar operaciones de asignacin dinmica de memoria. Permiten efectuar operaciones con estructuras de datos dinmicas.
Los punteros deben usarse con precaucin, ya que pueden provocar fallos en el programa difciles de localizar, puede ser por asignacin incorrecta de direccin.
As, por ejemplo, si se define un puntero a float, no se le puede asignar la direccin de un carcter o un entero.
Por ejemplo, este segmento de cdigo no funcionar: Ejemplo: float *fp; char c; fp = &c; / * no es vlido * /
Existen dos operadores especiales de punteros: & y *. El operador de direccin (&) devuelve la direccin de memoria de su operando. El operador de indireccin (*) devuelve el contenido de la direccin apuntada por el operando.
Inicializacin Ejemplos de Asignacin esttica de memoria void main(){ int a; int* b; b = &a; //El puntero 'b' apunta a 'a'. }
En C se puede declarar un puntero de modo que apunte a cualquier tipo de dato, es decir, no se asigna a un tipo de dato especfico. El mtodo es declarar el puntero como un puntero void *, denominado puntero genrico.
Listas lineales
Simples
Tipos de listas
Circulares
Doble
-El ltimo elemento tiene que apuntar NULL. -En las listas hay un nodo especial que es el primero ya que guarda el inicio de la lista y a travs de ese nodo se puede recorrer la lista. -Si el nodo inicial es NULL indica que la lista est vacia.
Insertar Caso 1: Lista Vaca El proceso es muy simple, bastar con comprobar si la lista==NULL: nuevo->siguiente apunte a NULL. Lista apunte a nuevo.
10
NULL
10
5 sig
50
10 NULL
7 20
NULL
10
50 sig 10 NULL
10 5
sig
20 7
sig
50 10
NULL
sig
20 7
50
sig 10 NULL
10 5
sig
20 7
sig
void eliminar(int elem) { aux=inicio; while (aux!=NULL){ if (elem==aux->dato) break; ant=aux; aux=aux->sig; }//while if(aux==NULL) cout<<"elemento no encontrado\n"; else{ if (aux==inicio)//primer elemento inicio=aux->sig; else if (aux->sig==NULL)//ultimo 50 ant->sig=NULL; else 10 NULL ant->sig=aux->sig; delete(aux);} }
Cuerpo del programa Librera: #include <iostream.h> void main(){ int op; while (op<4) cout<<"Listas Dinamicas - Menu Principal\n\n"; cout<<"1.Insertar\n"; cout<<"2.Eliminar\n"; cout<<"3.Mostrar\n"; cout<<4.Salir\n\n"; cout<<"Seleccione una opcion: "; cin>>op; int dat; switch (op){ case 1: { cout<<"Dato: "; cin>>dat; insertar(dat); break; } case 2: { cout<<"Dato: "; cin>>dat;
Ejercicios propuestos de listas simple 1. Escribir una funcin que imprima el nmero de nodos de una lista simple. 2. Escribir una funcin que elimine el nodo que ocupa la posicin i (dada por el usuario) de una lista simple, siendo el nodo inicio que ocupa la posicin n1. 3. Escribir una funcin que no permita insertar datos no repetidos.
10
5
Ant Sig 20 80
80 8
Ant Sig 10 50
50
Declaracin: struct nodo{ int elem; nodo *sig; nodo *ant; }*inicio=NULL, *fin=NULL, *aux, *nuevo;
void insertar(){ int dato; nuevo=new nodo; cout<<"Ingrese numero: "; Inicio cin>>dato; 10 nuevo->elem=dato; if (inicio==NULL){//lista vacia 5 ant sig Null nuevo->sig=NULL; nuevo->ant=NULL; inicio=nuevo; fin=nuevo; } else if(dato<inicio->elem){//inserto al inicio 20 Nuevo-inicio 10 Inicio nuevo->sig=inicio; Ant Sig nuevo->ant=NULL; 4 Ant Sig 5 Null 10 20 null inicio->ant=nuevo; inicio=nuevo; } else if(dato>fin->elem){//inserto por el final nuevo->ant=fin; Nuevo 50 nuevo->sig=NULL; Inicio 20 10 Inicio fin->sig=nuevo; Ant Sig fin=nuevo; Ant Sig 8 4 Ant Sig 5 } 10 null Null 10 20 50 else{//se recorre la lista aux=inicio; while(aux!=NULL){ 80 Nuevo if(dato<aux->elem) break; aux=aux->sig; 6 ant sig Null }//while //se enlaza con el siguiente nuevo->sig=aux; nuevo->ant=aux->ant; Inicio 20 10 Inicio 50 80 aux->ant->sig=nuevo; Ant Sig Ant Sig Ant Sig aux->ant=nuevo; 8 4 Ant Sig 5 8 80 null Null 10 20 80 10 50 } }
void eliminar(){ int dato_eli; cout<<"Ingrese dato a eliminar: "; cin>>dato_eli; aux=inicio; while(aux!=NULL){ if(dato_eli==aux->elem) break; aux=aux->sig; } //se evaluan 4 casos if(aux==NULL){//no encontrado cout<<"elemento no encontrado\n"; } else if(aux==inicio){//borra el 1er nodo if((aux->sig==NULL) &&(aux->ant==NULL) ){ inicio=NULL; fin=NULL;} else{ 20 inicio=inicio->sig; inicio->ant=NULL;} 4 Ant Sig } Null 10 else if (aux==fin){//borra el ultimo nodo if((aux->sig==NULL) &&(aux->ant==NULL) ){ inicio=NULL; fin=NULL;}//if else{ Inicio 20 fin=fin->ant; fin->sig=NULL;} 4 Ant Sig 5 Null 10 } else{//cualquier otro nodo aux->ant->sig=aux->sig; Inicio 20 aux->sig->ant=aux->ant; } 4 Ant Sig 5 delete(aux); Null 50 }
Inicio 10
4 ant sig
Null
10 Inicio 5
Ant Sig null 50
Fin 50
8
Ant Sig 10 null
10 Fin
Ant Sig 20 null
50 8 Fin 8
Ant Sig 10 null
10
Ant Sig 20 50
50
void main(){ int opcion; while(opcion<4){ system("cls"); cout<<"\n1. Insertar\n"; cout<<"2. Mostrar\n"; cout<<"3. Eliminar\n"; cout<<"4. Salir\n"; cout<<"Seleccione: "; cin>>opcion; switch(opcion){ case 1:{insertar(); break;} case 2: { mostrar(); break;} case 3: {eliminar(); break;} } } }
1. Utilizar una lista doblemente enlazada para controlar una lista de pasajeros de una lnea area. El programa principal debe ser controlado por men y permitir al usuario visualizar los datos de un pasajero determinado (cedula, nombre, apellido, destino), insertar un nodo , eliminar un pasajero de la lista. 2. Crear una lista doble con las edades de 10 personas y una funcin que calcule el promedio
10
Inicio
5 ant Sig 10
Inicio 10
5
Ant Sig 10 20
20
4 Sig 10
Ant=10 Aux=10
void mostrar_circular(){
int contar_nodos(){ int cant=1; ant=inicio; aux=inicio->sig; while(aux!=inicio){ cant++; aux=aux->sig; } return(cant);
Inicio 10
5
Ant Sig 10 20
20
4 Sig 10
Ant=10 Aux=20
}
void menu(){ int opcion; while(opcion<4){ system("cls"); cout<<"1. Insertar\n"; cout<<"2. Mostrar\n"; cout<<"3. Contar Nodos\n"; cout<<"4. Salir\n"; cout<<"Seleccione: "; cin>>opcion; switch(opcion){ case 1:{insertar(); break;} case 2: { mostrar_circular(); break;} case 3: { cout<<"La lista tiene: "<<contar_nodos()<<" nodos\n"; break;} } }
} void main(){
menu(); }
Pila
#include <iostream.h> struct nodo{ int num; nodo *ant; }*inicio=NULL, *aux, *nuevo; void empilar(){ nuevo=new (nodo); cout<<"Elemento: "; cin>>nuevo->num; if(inicio==NULL){ nuevo->ant=NULL; inicio=nuevo; } else{ nuevo->ant=inicio; inicio=nuevo; } } void desempilar(){ aux=inicio; if(aux==NULL) cout<<"Pila Vacia\n"; else if(aux->ant==NULL) inicio=NULL; else inicio=inicio->ant; delete(aux); cout<<"elemento borrado\n"; } void mostrar(){ aux=inicio; if (aux==NULL) cout<<"\nLa pila esta
vacia\n";
while(aux!=NULL){ cout<<aux->num<<"\n"; aux=aux->ant; } }
void main(){
int opcion;
while(opcion<4){ cout<<"1. Empilar\n"; cout<<"2. Desempilar\n"; cout<<"3. Mostrar\n"; cout<<"4. Salir\n"; cout<<"Seleccione una opcion: "; cin>>opcion; switch(opcion){ case 1:{empilar(); break;} case 2:{desempilar(); break;} case 3:{mostrar(); break;} }//sw
}//w
}//v