Está en la página 1de 34

REPBLICA BOLIVARIANA DE VENEZUELA MINISTERIO DEL PODER POPULAR PARA LA DEFENSA UNIVERSIDAD NACIONAL EXPERIMENTAL DE LA FUERZA ARMADA NCLEO

FALCN - EXTENSIN PUNTO FIJO

Docente: Licda. Marialix Quintero


Punto Fijo, Mayo de 2011

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

Definicin. Ventajas y desventajas. Declaracin / Inicializacin Punteros NULL y void

Punteros o apuntadores (Direcciones en memoria)


El proceso de asignacin dinmica de memoria permite crear y destruir variables en tiempo de ejecucin (variables dinmicas). Cuando una variable se declara, se asocian tres atributos fundamentales con la misma: su nombre, su tipo y su direccin en memoria. Ejemplo: n int n; int / * asocia al nombre n, el tipo int y la direccin de alguna posicin de memoria donde se almacena el valor de n* / -Al valor de una variable se accede por medio de su nombre. Por ejemplo, se puede imprimir el valor de n con la sentencia: cout<<n; -A la direccin de la variable se accede por medio del operador de direccin &. Por ejemplo, se puede imprimir la direccin de n con la sentencia: cout<<&n;
Ox4f f fd34

Punteros o apuntadores (Direcciones en memoria)


Ejemplo: Hacer un programa muestre por pantalla el valor y la direccin de una variable x de tipo entero. #include <stdio.h> void main() { int n = 75; cout<<el valor de n es: <<n; cout<<la direccin de memoria de n es: <<&n; } Ojo: la direccin viene dada en hexadecimal

Punteros o apuntadores (Definicin)


Puntero= variable direccin de memoria direccin de memoria de otra variable

= Puntero a punta a otra variable

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.

Punteros o apuntadores (Ejemplos)


Cuando se enva una carta por correo, su informacin se entrega basada en un puntero que es la direccin de esa carta.

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.

Punteros o apuntadores (Ventajas y desventajas)

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.

Punteros o apuntadores (Ventajas y desventajas)


Los tipos de datos tienen que corresponderse es decir (declaracin de variable de tipo de dato). Los punteros se enlazan a tipos de datos especficos, de modo que C verificar si se asigna la direccin de un tipo de dato al tipo correcto de puntero.

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.

Punteros o apuntadores (Declaracin e inicializacin)


Declaracin tipo_de_dato *nombre_var_puntero ej: int *punt; float *nuevo;

Inicializacin Ejemplos de Asignacin esttica de memoria void main(){ int a; int* b; b = &a; //El puntero 'b' apunta a 'a'. }

Punteros o apuntadores (Punteros Null y void)


Existen dos tipos de punteros especiales muy utilizados en el tratamiento de sus programas: los punteros void y null (nulo). Un puntero nulo no apunta a ninguna parte -dato vlido- en particular, es decir, un puntero nulo no direcciona ningn dato vlido en memoria. Un puntero nulo se utiliza para proporcionar a un programa un medio de conocer cuando una variable puntero no direcciona a un dato vlido. Para declarar un puntero nulo se utiliza la macro NULL, definida en los archivos de cabecera STDEF . H, STDIO. H, STDLIB. H y STRING. H. Se debe incluir uno o ms de estos archivos de cabecera antes de que se pueda utilizar la macro NULL. Ejemplos: char *p = NULL; Esttico nuevo->sig=NULL; Dinmico 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.

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

Definicin. Tipos de listas. Operaciones con listas.

Listas lineales (Definicin)


Las estructuras dinmicas nos permiten crear estructuras de datos que se adapten a las necesidades reales a las que suelen enfrentarse nuestros programas. Pero no slo eso, tambin nos permitir crear estructuras de datos muy flexibles, ya sea en cuanto al orden, la estructura interna o las relaciones entre los elementos que las componen. Las estructuras de datos estn compuestas de otras pequeas estructuras a las que llamaremos nodos o elementos, que agrupan los datos con los que trabajar nuestro programa y adems uno o ms punteros autoreferenciales, es decir, punteros a objetos del mismo tipo nodo. Una estructura bsica de un nodo para crear listas de datos seria: struct nodo { int dato; struct nodo *sig; };

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.

Lista simple o abierta


Es una coleccin o secuencia de elementos dispuestos uno detrs de otro, en la que cada elemento se conecta al siguiente elemento por un enlace o puntero. La idea bsica consiste en construir una lista cuyos elementos llamados nodos se componen de dos partes o campos: la primera parte o campo contiene la informacin y la segunda parte el puntero que guarda la direccin de memoria del siguiente nodo de la lista o valdr NULL si es el ltimo elemento. En las listas abiertas existe un nodo especial: el primero. Normalmente diremos que nuestra lista es un puntero a ese primer nodo y llamaremos a ese nodo la cabeza de la lista. Eso es porque mediante ese nico puntero podemos acceder a toda la lista. Cuando el puntero que usamos para acceder a la lista vale NULL, diremos que la lista est vaca. LAS LISTAS SON ORDENADAS

Lista simple o abierta (Operaciones con listas)


Declaracin: struct nodo{ int dato; struct nodo *siguiente; } *nuevo,*aux,*a nt, *inicio=NULL; Inicializacin: inicio=NULL;

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.

Cdigo if (inicio==NULL){ nuevo=new nodo; nuevo->dato=elem; nuevo->sig=NULL; inicio=nuevo; }

10

NULL

Lista simple o abierta (Operaciones con listas)


Caso 2: Insertar un elemento en la primera posicin de la lista (menor que el 1er elemento) El proceso sigue siendo muy sencillo: Hacemos que nodo->siguiente apunte a Lista. Hacemos que Lista apunte a nodo.

Cdigo: else if (elem<=inicio->dato){ nuevo=new nodo; nuevo->dato=elem; nuevo->sig=inicio; inicio=nuevo; }

10
5 sig

50
10 NULL

Lista simple o abierta (Operaciones con listas)


Caso 3: Insertar un elemento despus de un nodo cualquiera de la lista Procedimiento Recorrer la lista e ir guardando el anterior cuando se encuentre la posicin correcta, el anterior debe apuntar al nuevo nodo y el nuevo->siguiente a la posicin siguiente del anterior. else { aux=inicio; while (aux!=NULL){ if (elem<aux->dato) break; ant=aux; aux=aux->sig; } nuevo=new nodo; nuevo->dato=elem; ant->sig=nuevo; nuevo->sig=aux; }
Aux=10-50 Elem=7 Ant=10

7 20

NULL

10

50 sig 10 NULL

10 5

sig

20 7

sig

50 10

NULL

Lista simple o abierta (Operaciones con listas)


Recorrer / Mostrar void mostrar() { nodo *aux; aux=inicio; while(aux!=NULL){ cout<<"\t"<<aux->dato<<"\n"; aux=aux->sig;} aux=lista;} 10 5

sig

20 7

50
sig 10 NULL

Lista simple o abierta (Operaciones con listas)


Buscar / Eliminar: Se debe recorrer la lista buscando el elemento a borrar, tomando en cuenta su posicin en la lista: si es el primer elemento, el ltimo o esta en el medio.

Aux=10-20 Elem=7 Ant=10

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);} }

Lista simple o abierta (Operaciones con listas)

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.

Lista doble (Operaciones con listas)


10 5 ant sig Inicio 20 4
Ant Sig Null 10

10
5
Ant Sig 20 80

80 8
Ant Sig 10 50

50

Ant Sig 80 null

Declaracin: struct nodo{ int elem; nodo *sig; nodo *ant; }*inicio=NULL, *fin=NULL, *aux, *nuevo;

void mostrar(){ aux=inicio;


if (aux==NULL) cout<<"\nLista Vacia"; while(aux!=NULL){ cout<<aux->elem<<"\t"; aux=aux->sig; } }

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

Ant Sig 20 null

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;} } } }

Lista doble (Operaciones con listas) Ejercicios

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

Lista circular (Operaciones con listas)


#include <iostream.h> #include <iostream> struct nodo{ int dato; nodo *sig; }*inicio=NULL, *nuevo=NULL, *ant, *aux, *sigue; void insertar() { nuevo=new (nodo); cout<<"Elemento: "; cin>>nuevo->dato; if(inicio==NULL){ inicio=nuevo; nuevo->sig=inicio; }else { ant=inicio; aux=inicio->sig; while(aux!=inicio) {ant=aux; aux=aux->sig;} ant->sig=nuevo; nuevo->sig=inicio; } }

10

Inicio
5 ant Sig 10

Inicio 10
5

Ant Sig 10 20

20
4 Sig 10

Ant=10 Aux=10

void mostrar_circular(){

if(inicio!=NULL){//lista no vacia ant=inicio; aux=inicio->sig; cout<<ant->dato<<"\n"; while((aux!=inicio)&&(aux!=NULL)){ cout<<aux->dato<<"\n"; aux=aux->sig; } }


}

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(); }

Lista circular (Operaciones con listas)


Hacer un programa que almacene en una Lista Circular, la nota definitiva de 10 alumnos de lenguajes de programacin, y muestre la nota ms alta y el promedio de la seccin.

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