34
REPÚBLICA BOLIVARIANA DE VENEZUELA MINISTERIO DEL PODER POPULAR PARA LA DEFENSA UNIVERSIDAD NACIONAL EXPERIMENTAL DE LA FUERZA ARMADA NÚCLEO FALCÓN - EXTENSIÓN PUNTO FIJO Docente: Licda. Marialix Quintero Punto Fijo, Mayo de 2011

Apuntadores y listas

Embed Size (px)

DESCRIPTION

En esta presentación se desarrollarán temas relacionados a apuntadores, listas (simples, circulares y doble) y por último una antesala a la pila

Citation preview

Page 1: Apuntadores y listas

REPÚBLICA BOLIVARIANA DE VENEZUELA MINISTERIO DEL PODER POPULAR PARA LA DEFENSA

UNIVERSIDAD NACIONAL EXPERIMENTAL DE LAFUERZA ARMADA

NÚCLEO FALCÓN - EXTENSIÓN PUNTO FIJO

Docente:Licda. Marialix Quintero

Punto Fijo, Mayo de 2011

Page 2: Apuntadores y listas

Una de las aplicaciones más interesantes y potentes de la memoria dinámica y los punteros son las estructuras dinámicas de datos. Las estructuras básicas disponibles en C y C++ tienen una importante limitación: no pueden cambiar de tamaño durante la ejecución. Los arreglos están compuestos por un determinado número de elementos, número que se decide en la fase de diseño, antes de que el programa ejecutable sea creado. En muchas ocasiones se necesitan estructuras que puedan cambiar de tamaño durante la ejecución del programa. Por supuesto, podemos hacer 'arrays' dinámicos, pero una vez creados, tu tamaño también será fijo, y para hacer que crezcan o diminuyan de tamaño, deberemos reconstruirlas desde el principio, por este motivo los arrays no hacen un uso eficiente de la memoria.

Page 3: Apuntadores y listas

OBJETIVOSOBJETIVOS

1. Entender la eficacia del manejo de la memoria dinámica a través del uso de apuntadores

2. Lograr un uso eficiente de las estructuras de datos lineales.

Page 4: Apuntadores y listas

Definición.Ventajas y desventajas.Declaración / InicializaciónPunteros NULL y void

Punteros o apuntadoresPunteros o apuntadores

Page 5: Apuntadores y listas

Punteros o apuntadoresPunteros o apuntadores(Direcciones en memoria)(Direcciones en memoria)

El proceso de asignación dinámica de memoria permite crear y destruir variables en tiempo de ejecución (variables dinámicas). Cuando una variable se declara, se asocian tres atributos fundamentales con la

misma: su nombre, su tipo y su dirección en memoria.

Ejemplo:int n;

/ * asocia al nombre n, el tipo int y la dirección de alguna posición 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;cout<<n;

-A la dirección de la variable se accede por medio del operador de dirección &.

Por ejemplo, se puede imprimir la dirección de n con la sentencia: cout<<&n;cout<<&n;

Ox4f f fd34Ox4f f fd34

nn

intint

Page 6: Apuntadores y listas

Ejemplo: Hacer un programa muestre por pantalla el valor y la dirección de una variable x de tipo

entero.#include <stdio.h>

void main(){

int n = 75;cout<<”el valor de n es: ”<<n;

cout<<”la dirección de memoria de n es: ”<<&n;}

Ojo: la dirección viene dada en hexadecimal

Punteros o apuntadoresPunteros o apuntadores(Direcciones en memoria)(Direcciones en memoria)

Page 7: Apuntadores y listas

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 dirección de memoria, y utilizando punteros su programa puede realizar muchas tareas

que no sería posible utilizando tipos de datos estándar.

Punteros o apuntadoresPunteros o apuntadores(Definición)(Definición)

Puntero= variable dirección de memoria dirección de memoria de otra variablePuntero= variable dirección de memoria dirección de memoria de otra variable

==Puntero a punta a otra variablePuntero a punta a otra variable

Page 8: Apuntadores y listas

Cuando se telefonea a una persona, se utiliza un puntero Cuando se telefonea a una persona, se utiliza un puntero (el número de teléfono que se marca). (el número de teléfono que se marca).

Punteros o apuntadoresPunteros o apuntadores(Ejemplos)(Ejemplos)

Cuando se envía una carta por correo, su información Cuando se envía una carta por correo, su información se entrega basada en un puntero que es la dirección se entrega basada en un puntero que es la dirección de esa carta.de esa carta.

Así pues, una dirección de correos y un número de teléfono tienen en común que ambos indican dónde encontrar algo.

Page 9: Apuntadores y listas

Punteros o apuntadoresPunteros o apuntadores(Ventajas y desventajas)(Ventajas y desventajas)

•Los punteros tienen una gran Los punteros tienen una gran utilidad, pues permiten una utilidad, pues permiten una programación eficaz a nivel de programación eficaz a nivel de máquina cuando se maneja la máquina cuando se maneja la memoria del ordenador.memoria del ordenador.

•Permiten realizar operaciones Permiten realizar operaciones de asignación dinámica de de asignación dinámica de memoria.memoria.

•Permiten efectuar operaciones Permiten efectuar operaciones con estructuras de datos con estructuras de datos dinámicas.dinámicas.

Los punteros deben usarse con Los punteros deben usarse con precaución, ya que pueden precaución, ya que pueden provocar fallos en el programa provocar fallos en el programa difíciles de localizar, puede ser difíciles de localizar, puede ser por asignación incorrecta de por asignación incorrecta de dirección.dirección.  

Page 10: Apuntadores y listas

Los tipos de datos tienen que corresponderse es decir (declaración de variable de tipo de dato). Los punteros se enlazan a tipos de datos específicos, de modo que

C verificará si se asigna la dirección 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 dirección de un carácter o un entero.

Por ejemplo, este segmento de código no funcionará:Ejemplo:float *fp;char c;

fp = &c; / * no es válido * /

Existen dos operadores especiales de punteros: & y *. El operador de dirección (&) devuelve la dirección de memoria de su operando. El operador de indirección (*)

devuelve el contenido de la dirección apuntada por el operando.

Punteros o apuntadoresPunteros o apuntadores(Ventajas y desventajas)(Ventajas y desventajas)

Page 11: Apuntadores y listas

InicializaciónInicialización

Ejemplos de Asignación estática de memoriaEjemplos de Asignación estática de memoriavoid main(){void main(){

int a;int a;int* b;int* b;

b = &a;         //El puntero 'b' apunta a 'a'.b = &a;         //El puntero 'b' apunta a 'a'.}}

Punteros o apuntadoresPunteros o apuntadores(Declaración e inicialización)(Declaración e inicialización)

DeclaraciónDeclaracióntipo_de_dato *nombre_var_punterotipo_de_dato *nombre_var_punteroej: int *punt;ej: int *punt; float *nuevo;float *nuevo;

Page 12: Apuntadores y listas

Existen dos tipos de punteros especiales muy utilizados en el tratamiento de sus programas: los Existen dos tipos de punteros especiales muy utilizados en el tratamiento de sus programas: los punteros void y null (nulo).punteros void y null (nulo).

Un Un puntero nulo puntero nulo no apunta a ninguna parte -dato válido- en particular, es decir, «un puntero nulo no apunta a ninguna parte -dato válido- en particular, es decir, «un puntero nulo no direcciona ningún dato válido en memoria». Un puntero nulo se utiliza para proporcionar a un no direcciona ningún dato válido 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 válido. Para programa un medio de conocer cuando una variable puntero no direcciona a un dato válido. Para declarar un puntero nulo se utiliza la macro NULL, definida en los archivos de cabecera STDEF . 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 más de estos archivos de cabecera H, STDIO. H, STDLIB. H y STRING. H. Se debe incluir uno o más de estos archivos de cabecera

antes de que se pueda utilizar la macro NULL.antes de que se pueda utilizar la macro NULL.Ejemplos:Ejemplos:

char *p = NULL; Estáticochar *p = NULL; Estáticonuevo->sig=NULL; Dinámiconuevo->sig=NULL; Dinámico

En C se puede declarar un puntero de modo que apunte a cualquier tipo de dato, es decir, no se 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 específico. asigna a un tipo de dato específico.

En C se puede declarar un puntero de modo que apunte a cualquier tipo de dato, es decir, no se 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 específico. El método es declarar el puntero como un puntero void *, asigna a un tipo de dato específico. El método es declarar el puntero como un puntero void *,

denominado puntero genérico. denominado puntero genérico.

Punteros o apuntadoresPunteros o apuntadores(Punteros Null y void)(Punteros Null y void)

Page 13: Apuntadores y listas

Definición.Tipos de listas.Operaciones con listas.

Listas linealesListas lineales

Page 14: Apuntadores y listas

Las estructuras dinámicas nos permiten crear estructuras de datos que se adapten a las necesidades reales a las que suelen

enfrentarse nuestros programas.

Pero no sólo eso, también 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 están compuestas de otras pequeñas estructuras a las que llamaremos nodos o elementos, que agrupan los datos con los que trabajará nuestro programa y además uno o más punteros autoreferenciales, es decir, punteros a objetos del

mismo tipo nodo.

Una estructura básica de un nodo para crear listas de datos seria:struct nodo { int dato;

struct nodo *sig;};

Listas lineales (Definición)Listas lineales (Definición)

Page 15: Apuntadores y listas

Tipos de listasTipos de listas

SimplesSimples

CircularesCirculares

DobleDoble

-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 través de ese nodo se puede recorrer la lista.-Si el nodo inicial es NULL indica que la lista está vacia.

Page 16: Apuntadores y listas

•Es una colección o secuencia de elementos dispuestos uno detrás de otro, en la que cada elemento se conecta al siguiente elemento por un «enlace» o «puntero».

•La idea básica consiste en construir una lista cuyos elementos llamados nodosnodos se componen de dos partes o campos: la primera parte o campo contiene la informaciónla información y la segunda parte el puntero que guarda la dirección de memoria del siguiente nodola dirección 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á vacía. “LAS LISTAS SON ORDENADAS”“LAS LISTAS SON ORDENADAS”

Lista simple o abiertaLista simple o abierta

Page 17: Apuntadores y listas

Declaración:Declaración:struct nodo{struct nodo{

int dato;int dato;struct nodo struct nodo

*siguiente;*siguiente;} }

*nuevo,*aux,*a*nuevo,*aux,*ant, nt,

*inicio=NULL;*inicio=NULL;

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

Inicialización:Inicialización: inicio=NULL;inicio=NULL;

InsertarCaso 1: Lista Vacía

El proceso es muy simple, bastará con comprobar si la lista==NULL:nuevo->siguiente apunte a NULL.

Lista apunte a nuevo.

Códigoif (inicio==NULL){

nuevo=new nodo;nuevo->dato=elem;nuevo->sig=NULL;

inicio=nuevo;}

10 NULL

Page 18: Apuntadores y listas

Caso 2: Insertar un elemento en la primera posición 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.

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

Código:else if (elem<=inicio->dato){

nuevo=new nodo;nuevo->dato=elem;nuevo->sig=inicio;

inicio=nuevo;}

10 NULL5 sig

10

50

Page 19: Apuntadores y listas

Caso 3: Insertar un elemento después de un nodo cualquiera de la lista

ProcedimientoRecorrer la lista e ir guardando el anterior

cuando se encuentre la posición correcta, el anterior debe apuntar al nuevo nodo y el nuevo->siguiente a la posición siguiente del anterior.

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

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

10 NULL5

sig

Aux=10-50Elem=7Ant=10

7 NULL

10

50

20

5

sig10 7

sig

20 10

NULL

50

Page 20: Apuntadores y listas

Recorrer / Mostrarvoid mostrar()

{nodo *aux;aux=inicio;

while(aux!=NULL){cout<<"\t"<<aux->dato<<"\n";

aux=aux->sig;}aux=lista;}

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

5

sig10 7

sig

20 10

NULL

50

Page 21: Apuntadores y listas

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

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)//ultimoant->sig=NULL;

elseant->sig=aux->sig;

delete(aux);}}

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

5

sig10 7

sig

20 10

NULL

50

Aux=10-20Elem=7Ant=10

Page 22: Apuntadores y listas

Cuerpo del programaLibrería: #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; eliminar(dat);

break;} case 3:{

mostrar(); break;

} }

} }

Lista simple o abierta (Operaciones con listas)Lista simple o abierta (Operaciones con listas)

Page 23: Apuntadores y listas

Ejercicios propuestos de listas simpleEjercicios propuestos de listas simple

1.1. Escribir una función que imprima el número de Escribir una función que imprima el número de nodos de una lista simple.nodos de una lista simple.

2.2. Escribir una función que elimine el nodo que Escribir una función que elimine el nodo que ocupa la posición i (dada por el usuario) de ocupa la posición i (dada por el usuario) de una lista simple, siendo el nodo inicio que una lista simple, siendo el nodo inicio que ocupa la posición n°1.ocupa la posición n°1.

3.3. Escribir una función que no permita insertar Escribir una función que no permita insertar datos no repetidos.datos no repetidos.

Page 24: Apuntadores y listas

Declaración:Declaración:struct nodo{struct nodo{

int elem;int elem;nodo *sig;nodo *sig;nodo *ant;nodo *ant;

}*inicio=NULL, }*inicio=NULL, *fin=NULL, *fin=NULL,

*aux, *nuevo;*aux, *nuevo;

Lista doble (Operaciones con listas)Lista doble (Operaciones con listas)

5

sig10 ant

void mostrar(){aux=inicio;

if (aux==NULL) cout<<"\nLista Vacia";

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

}}

Inicio

4

Sig10

AntNull

5

Sig80

Ant20

20 8

Signull

Ant80

10

50 8

Sig50

Ant10

80

Page 25: Apuntadores y listas

void insertar(){int dato;nuevo=new nodo;cout<<"Ingrese numero: ";cin>>dato;nuevo->elem=dato;if (inicio==NULL){//lista vacia

nuevo->sig=NULL;nuevo->ant=NULL;inicio=nuevo;fin=nuevo;

}else if(dato<inicio->elem){//inserto al inicio

nuevo->sig=inicio;nuevo->ant=NULL;inicio->ant=nuevo;inicio=nuevo;

}else if(dato>fin->elem){//inserto por el final

nuevo->ant=fin;nuevo->sig=NULL;fin->sig=nuevo;fin=nuevo;

}else{//se recorre la lista

aux=inicio;while(aux!=NULL){

if(dato<aux->elem) break;aux=aux->sig;

}//while//se enlaza con el siguientenuevo->sig=aux;nuevo->ant=aux->ant;aux->ant->sig=nuevo;aux->ant=nuevo;}

}

5

sig10 ant

4

Sig10

20 Ant

Null5

Signull

10 Ant

20

Inicio

InicioNuevo-inicio

InicioInicio

Null

Nuevo

4

Sig10

AntNull

5

Sig50

Ant20

20 8

Signull

Ant10

10

50

6

sig

80 ant Null

InicioInicio

4

Sig10

AntNull

5

Sig80

Ant20

20 8

Signull

Ant80

10

50 8

Sig50

Ant10

80

Nuevo

Page 26: Apuntadores y listas

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 casosif(aux==NULL){//no encontradocout<<"elemento no encontrado\n";}else if(aux==inicio){//borra el 1er nodo if((aux->sig==NULL) &&(aux->ant==NULL) ){ inicio=NULL;

fin=NULL;}else{inicio=inicio->sig;inicio->ant=NULL;}

}else if (aux==fin){//borra el ultimo nodo

if((aux->sig==NULL) &&(aux->ant==NULL) ){ inicio=NULL; fin=NULL;}//if

else{fin=fin->ant;fin->sig=NULL;}

}else{//cualquier otro nodo

aux->ant->sig=aux->sig;aux->sig->ant=aux->ant;

}delete(aux);

}

Inicio Fin

4

Sig10

AntNull

5

Signull

Ant20

20 8

Signull

Ant10

10

50

4

sig

10

ant

Inicio

Null

Inicio

4

Sig10

AntNull

5

Sig50

Antnull

20 8

Signull

Ant10

10

50

Fin

Inicio

4

Sig50

AntNull

5

Sig50

Ant20

20 8

Signull

Ant20

10

50

Fin

Page 27: Apuntadores y listas

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

}}

Page 28: Apuntadores y listas

Lista doble (Operaciones con listas) EjerciciosLista doble (Operaciones con listas) Ejercicios

1. Utilizar una lista doblemente enlazada para controlar una lista de pasajeros de una línea aérea. 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 función que calcule el promedio

Page 29: Apuntadores y listas

Lista circular (Operaciones con listas)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;

}}

5

Sig10

10

ant

Inicio

5

Sig20

10 Ant

10

Inicio

4

Sig10

Ant=10Aux=10

20

Page 30: Apuntadores y listas

void mostrar_circular(){

if(inicio!=NULL){//lista no vaciaant=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);

}

5

Sig20

10 Ant

10

Inicio

4

Sig10

Ant=10Aux=20

20

Page 31: Apuntadores y listas

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

Page 32: Apuntadores y listas

Hacer un programa que almacene en una Lista Circular, la nota definitiva de 10 alumnos de lenguajes de programación, y muestre la nota más alta y el promedio de la sección.

Lista circular (Operaciones con listas)Lista circular (Operaciones con listas)

Page 33: Apuntadores y listas

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

}}

Page 34: Apuntadores y listas

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