0% encontró este documento útil (0 votos)
2K vistas143 páginas

Libro C++

Este documento presenta un resumen de las estructuras de datos en C++. Comienza con una introducción al lenguaje C++, incluyendo conceptos básicos como variables, tipos de datos, estructuras de control y funciones. Luego describe estructuras de datos estáticas como vectores, matrices y registros, y estructuras dinámicas como punteros, vectores dinámicos y listas enlazadas. Finalmente, cubre temas como algoritmos de ordenamiento, búsqueda y programación orientada a objetos. El documento proporciona ejemplos de código

Cargado por

Cristhian Galan
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
2K vistas143 páginas

Libro C++

Este documento presenta un resumen de las estructuras de datos en C++. Comienza con una introducción al lenguaje C++, incluyendo conceptos básicos como variables, tipos de datos, estructuras de control y funciones. Luego describe estructuras de datos estáticas como vectores, matrices y registros, y estructuras dinámicas como punteros, vectores dinámicos y listas enlazadas. Finalmente, cubre temas como algoritmos de ordenamiento, búsqueda y programación orientada a objetos. El documento proporciona ejemplos de código

Cargado por

Cristhian Galan
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 143

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

ESTRUCTURAS DE DATOS EN C++

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

ESTRUCTURAS DE DATOS EN C++

Luisa Mireya Rojas Mendoza Ingeniera de Sistemas C. L. Universidad Industrial de Santander Especialista en Educacin con Nuevas Tecnologas de la Informacin y la Comunicacin Universidad Autnoma de Bucaramanga - UNAB Bucaramanga - Colombia

FACULTAD DE INGENIERA FUNDACIN UNIVERSITARIA DE SAN GIL UNISANGIL YOPAL CASANARE COLOMBIA 2006

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

A mi padre y hermano que desde el cielo, como ngeles, me acompaan siempre; y a mi madre que desde la tierra me aconseja y comprende A mi gran amor

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

AGRADECIMIENTOS

Mi agradecimiento a cuantas personas han hecho posible la realizacin del presente texto, especialmente a todos los estudiantes de la asignatura Estructuras de Datos del programa de Ingeniera de Sistemas Unisangil Yopal Casanare, porque con sus sugerencias y forma de trabajar en la asignatura hicieron posible este trabajo. Agradezco la colaboracin de mis compaeros la Ingeniera de Sistemas Ivonne Zulay Dueas Amaris, el Ingeniero de Sistemas Jimmy Yordany Ardila y el Ingeniero Electromecnico Wilson Arturo Gmez que en este y otros proyectos han aportado su conocimiento y calidades humanas.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

CONTENIDO

CONTENIDO 5 PREFACIO 14 1.GENERALIDADES DEL LENGUAJE C++ ................................................................. 16 1.1.ESTRUCTURA BSICA DE UN PROGRAMA 16 1.1.ESTRUCTURA BSICA DE UN PROGRAMA 16 1.2.CONCEPTOS BSICOS DE C++ 17 1.2.1.Alfabeto 17 1.2.2.Libreras 18 1.2.3.Directivas 19 1.2.4.Variables 19 1.2.5.Constantes 21 1.3.TIPOS DE DATOS 21 1.3.1.Tipos de datos Numricos 21 1.3.2.Tipos de datos Caracter 22 1.4.LECTURA Y ESCRITURA EN C++ 24 1.4.1.Librera stdio.h 24 1.4.2.Librera conio.h 26 1.4.3. Librera iostream.h 26 1.5.ESTRUCTURAS DE CONTROL 26 1.5.1.Asignaciones 27 1.5.2.Estructuras condicionales 28 1.5.3.Estructuras iterativas 32 1.6.FUNCIONES 35 1.6.1.Funciones que no retornan un nico valor 35 1.6.2.Funciones que retornan un nico valor 36 1.6.3.Paso de parmetros por valor 37 1.6.4.Paso de parmetros por referencia 38 1.6.5. Sobrecarga de Funciones 39 2.ESTRUCTURAS DE DATOS ESTTICAS ............................................................. 41 2.1.VECTORES 41 2.1.1.Definicin de vector 41 2.1.2.Actividades en Vectores 42 2.2.MATRICES 46

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

2.2.1.Definicin de matriz 46 2.2.2.Actividades en Matrices 47 2.3.REGISTROS 52 2.3.1.Definicin de un registro 52 2.3.2.Declaracin de variables registros 52 2.3.3.Arreglo de registros 54 3.ESTRUCTURAS DE DATOS DINMICAS ............................................................63 3.1.PUNTEROS 63 3.1.1.Declaracin de una variable de tipo puntero 64 3.1.2. Asignacin de memoria a un puntero 64 3.1.3.Asignacin de un valor a un puntero 64 3.2.PUNTEROS Y VECTORES 66 3.3.VECTORES DINMICOS 68 3.4.LISTAS SIMPLEMENTE ENLAZADAS 69 3.4.1.Definicin y declaracin de los elementos de una lista simple enlazada69 3.4.2.Creacin y recorrido de una lista simplemente enlazada 70 3.5.LISTAS SIMPLEMENTE ENLAZADAS CON PROCEDIMIENTOS Y FUNCIONES 72 3.5.1.Creacin de la lista 72 3.5.2.Recorrer la lista 73 3.5.3.Insercin de un nodo 73 3.5.4.Borrar un nodo 76 Tipo de chofer 83 3.6.LISTAS DOBLEMENTE ENLAZADAS 84 3.6.1.Creacin de la lista doble 84 3.6.2.Recorrer la lista doblemente enlazada hacia la derecha 86 3.6.3.Recorrer la lista doblemente enlazada hacia la izquierda 87 3.6.4.Insertar un nodo al comienzo de la lista 87 3.6.5.Insertar un nodo antes de un valor dado 89 3.6.6.Insertar un nodo al final de la lista 92 3.6.7.Borrar al comienzo de la lista 93 3.6.8.Borrar el ltimo nodo de la lista 95 3.6.9.Borrar un nodo cualquiera de la lista 96 4.ALGORITMOS DE ORDENAMIENTO ................................................................... 111 4.1.BURBUJA MEJORADO 112 4.2.MTODO SHELL 114 4.3.QUICKSORT 119

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

5.ALGORITMOS DE BSQUEDA.............................................................................. 127 5.1.BSQUEDA BINARIA 127 5.2.BUSQUEDA SECUENCIAL 129 6.PROGRAMACIN ORIENTADA A OBJETOS ................................................. 132 6.1.DEFINICIN DE REQUISITOS DE UN SISTEMA 132 6.2.DEFINICIN DEL DOMINIO DE UN SISTEMA 133 6.2.1.Objetos y Clases 133 6.2.2.Mtodos de una clase 135 6.2.3.Llamada de datos y funciones (Mtodos) 135 6.2.4.Mtodos de acceso 136 6.2.5.Mtodos constructores y destructores 137 6.2.6.Composicin de clases 139 6.2.7.Sobrecarga de Operadores 139 6.2.8.Funciones amigo y clases amigo 141 6.3. COMPONENTES DEL SISTEMA 143 7.BIBLIOGRAFA.......................................................................................................... 145

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

LISTA DE EJEMPLOS Ejemplo 1. Programa bsico en C++ 15 Ejemplo 2. Programa que usa gets y puts 24 Ejemplo 3. Funcin de tipo void 34 Ejemplo 4. Funciones que retornan un nico valor 35 Ejemplo 5. Funcin con paso de parmetros por valor y referencia 36 Ejemplo 6. Sobrecarga de funciones 37 Ejemplo 7. Lectura de un vector 41 Ejemplo 8. Recorrido de un vector 41 Ejemplo 9. Impresin de un vector 42 Ejemplo 10. Lectura de matrices 46 Ejemplo 11. Recorrido de matrices 47 Ejemplo 12. Impresin de una matriz 47 Ejemplo 13. Programa sencillo de matrices 48 Ejemplo 14. Registros 51 Ejemplo 15. Registro de un estudiante 51 Ejemplo 16. Arreglo de registros 53 Ejemplo 17. Archivo de una empresa 54 Ejemplo 18. Puntero a un entero 63 Ejemplo 19. Asignacin de memoria a un puntero 63 Ejemplo 20. Vector con punteros 65 Ejemplo 21. Vectores dinmicos 66 Ejemplo 22. Creacin de una lista simple 68 Ejemplo 23. Crear un nodo 70 Ejemplo 24. Mostrar la lista simplemente enlazada 71 Ejemplo 25. Insercin de un nodo en una lista simplemente enlazada 73 Ejemplo 26. Borrar un nodo de una lista simplemente enlazada 74 Ejemplo 27. Programa de una lista simplemente enlazada con procedimientos 75 Ejemplo 28. Crear un nodo en una lista doblemente enlazada 83 Ejemplo 29. Crear varios nodos en una lista doble 83 Ejemplo 30. Recorrido hacia la derecha en una lista doblemente enlazada 84 Ejemplo 31. Recorrido hacia la izquierda en una lista doblemente enlazada 85 Ejemplo 32. Insercin de un nodo al comienzo de una lista doblemente enlazada 86 Ejemplo 33. Insercin de un nodo antes de un valor dado en una lista doblemente enlazada 89 Ejemplo 34. Insercin de un nodo al final de una lista doblemente enlazada 91 Ejemplo 35. Borrar un nodo al comienzo de una lista doblemente enlazada 92

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

Ejemplo 36. Borrar el ltimo nodo de una lista doblemente enlazada Ejemplo 37. Programa completo lista doblemente enlazada Ejemplo 38. Programa Burbuja mejorado Ejemplo 39. Algoritmo ordenamiento SHELL Ejemplo 40. Programa completo del mtodo de ordenamiento SHELL Ejemplo 41. Mtodo de ordenamiento QUICKSORT Ejemplo 42. Mtodo de bsqueda binaria Ejemplo 43. Mtodo de bsqueda secuencial Ejemplo 44. Definicin de la clase estudiante Ejemplo 45. Implementacin de los mtodos de la clase estudiante Ejemplo 46. Llamada de los mtodos de una clase Ejemplo 47. Mtodos SET y GET Ejemplo 48. Mtodo constructor Ejemplo 49. Sobrecarga de operadores Ejemplo 50. Funciones amigas

93 97 111 115 115 123 126 128 132 133 134 135 136 137 140

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

10

LISTA DE FIGURAS

Figura 1. Variable almacenada en memoria Figura 2. Condicional 2 opciones Figura 3. Condicional mltiple Figura 4. Instruccin For. Figura 5. Ejemplo Instruccin For. Figura 6. Instruccin While. Figura 7. Instruccin do While. Figura 8. Representacin grfica de un vector Figura 9. Lectura o almacenamiento de informacin en un vector Figura 10. Recorrido en un vector Figura 11. Impresin de un vector. Figura 12. Representacin grfica de una matriz Figura 13. Lectura de una matriz Figura 14. Recorrido de una matriz Figura 15. Escritura de una matriz Figura 16. Puntero Figura 17. Lista simplemente enlazada Figura 18. Insercin de un nodo al comienzo de una lista simple Figura 19. Insercin de un nodo en medio de dos nodos en una lista simple Figura 20. Eliminacin del primer nodo de una lista simple Figura 21. Eliminacin de un nodo intermedio en una lista simple Figura 22. Lista doblemente enlazada Figura 23. Creacin de nodo en una lista doblemente enlazada Figura 24. Creacin de varios nodos en una lista doble Figura 25. Insertar un nodo al comienzo de la lista doble Figura 26. Insercin de un nodo antes de un valor dado en una lista doble Figura 27. Insercin de un nodo al final de una lista doble Figura 28. Borrar un nodo al comienzo de la lista doble Figura 29. Borrar el ltimo nodo de una lista doblemente enlazada Figura 30. Borrar un nodo cualquiera Figura 31. Caso de Uso administrar estudiantes Figura 32. Clase en UML Figura 33. Estructura de una clase en C++

18 27 29 30 31 31 32 39 40 41 42 45 46 46 47 61 67 72 72 74 74 82 82 83 86 87 91 92 93 94 130 132 142

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

11

LISTA DE CUADROS Cuadro 1. Secuencias de Escape Cuadro 2. Tipos de datos entero 16 bits Cuadro 3. Tipos de datos entero 32 bits Cuadro 4. Tipos de datos decimal 16 y 32 bits Cuadro 5. Tipos de datos carcter 16 y 32 bits. Cuadro 6. Tipos de datos que preceden % Cuadro 7. Operadores aritmticos Cuadro 8. Asignaciones no convencionales Cuadro 9. Operadores relacionales Cuadro 10. Operadores lgicos 16 19 20 20 21 22 26 26 28 29

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

12

PREFACIO

Una estructura de datos es un conjunto de datos simples interrelacionados entre s con el objetivo de almacenar y manipular la informacin de un sistema como un todo. Sobre las estructuras de datos se pueden realizar operaciones como adicionar, borrar y buscar valores, as como ordenar utilizando algn parmetro de referencia. Cada una de las estructuras de datos existentes, presentan ventajas o desventajas en cuanto a la simplicidad y eficiencia de las operaciones que se realizan sobre ellas y se pueden clasificar como estticas o dinmicas teniendo en cuenta la forma de almacenamiento en memoria durante la ejecucin del programa. Los desarrolladores de software para implementar sistemas computacionales como sistemas operativos, compiladores, sistemas empresariales de gestin y administracin de informacin, sistemas de acceso a bases de datos y sistemas de comunicaciones, entre otras aplicaciones, requieren identificar y manejar las estructuras de datos y conocer su forma de almacenamiento en el computador. Adems, el conocimiento sobre las estructuras de datos busca fomentar en los desarrolladores habilidades de pensamiento tales que les permitan brindar solucin a cualquier tipo de problema informtico. Igualmente, el anlisis, la evaluacin y el uso adecuado de algoritmos de mezcla, ordenamiento y bsqueda que utilizan estructuras de datos, sirven de marco de referencia para el desarrollo de algoritmos ms avanzados o complejos. El presente texto pretende mostrar algunos de los temas fundamentales en el manejo de las estructuras de datos que se utilizan en programacin para crear sistemas informticos. El captulo 1, presenta los elementos del lenguaje C++ esenciales para construir un programa bsico. Aqu se identifican los tipos de datos simples necesarios para formar estructuras de datos avanzadas, las instrucciones de lectura y escritura de datos y las estructuras de control como las estructuras condicionales y repetitivas. Adems, se tratan las funciones y procedimientos, bloques de cdigo usados en la programacin estructurada. El captulo 2, aborda las estructuras de datos de asignacin esttica de memoria, como los vectores, las matrices y los registros. Para cada una de estas estructuras, se

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

13

identifican las operaciones que se pueden realizar sobre stas como la lectura, el recorrido, la escritura, la bsqueda y el ordenamiento. El captulo 3, muestra las estructuras de asignacin dinmica de memoria, desde la ms simple como el puntero, hasta las ms complejas como las listas simplemente y doblemente enlazadas. El captulo 4 y 5, presenta los algoritmos de ordenacin y bsqueda ms utilizados en programacin, para la construccin de software de calidad bajo el principio de reutilizacin de cdigo. Finalmente, el captulo 6, presenta algunos ejemplos y definiciones de programacin orientada a objetos con C++. A quienes est dirigido el texto? El texto puede ser usado por la siguiente audiencia: Desarrolladores o estudiantes con experiencia en cualquier lenguaje de programacin, pero que son nuevos en el manejo de estructuras de datos. Aquellos familiarizados con estructuras de datos estticas como vectores y matrices que quieran conocer las estructuras de datos dinmicas y de mayor complejidad. Ejemplos El texto presenta ejemplos en lenguaje C++. Sin embargo, el manejo de las estructuras puede extenderse a cualquier lenguaje de programacin, con algunas restricciones.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

14

1. GENERALIDADES DEL LENGUAJE C++

1.1. 1.2. 1.3. 1.4. 1.5. 1.6.

ESTRUCTURA BSICA DE UN PROGRAMA CONCEPTOS BSICOS DE C++ TIPOS DE DATOS LECTURA Y ESCRITURA EN C++ ESTRUCTURAS DE CONTROL FUNCIONES

1.1.

ESTRUCTURA BSICA DE UN PROGRAMA

Un programa sencillo en C o C++ consta de dos bloques. El primer bloque denominado interface, contiene las cabeceras, directivas, declaraciones de variables, la definicin de tipos de datos, de constantes y de funciones. El segundo bloque denominado implementacin, es el cuerpo principal del programa, comienza con la funcin main o funcin principal y contiene declaraciones, proposiciones y sentencias, como estructuras de control e instrucciones de lectura y escritura.

Interface

Cabeceras o libreras Directivas Declaracin de variables globales Definicin de constantes y tipos de datos lnea de cabecera de la funcin principal. Cuerpo de la funcin principal: Declaraciones, Sentencias, Proposiciones Estructuras de control Instrucciones de lectura y escritura

void main() { Inicio de bloque

Implementacin

} Fin de bloque

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

15

Cada una de las partes que conforman la interface e implementacin sern explicadas en las secciones siguientes. Ejemplo 1. Programa bsico en C++ #include <stdio.h> #include <conio.h> #include <iostream.h> void main() { int a, b, c; cout<<"El valor del primer numero es: \n"; cin>>a; cout<<"El valor del segundo numero es: \n"; cin>>b; c = a + b; cout<<"La suma es: "<<c; getch(); }

1.2.

CONCEPTOS BSICOS DE C++

El lenguaje C++ se deriva del lenguaje C y es considerado como un lenguaje orientado a objetos, aunque no puro como lo es, por ejemplo java. C++ es potente en la programacin a bajo nivel e igualmente potente en la programacin de alto nivel.

1.2.1.

Alfabeto

En C++ se utilizan los caracteres del alfabeto ASCII, compuesto por las letras maysculas y minsculas del alfabeto ingls, desde la letra a...z y A...Z. Adems, se utilizan los dgitos del 0 al 9, el carcter de espaciar, los caracteres de control como nueva lnea, tabuladores horizontal y vertical, nueva pgina y los smbolos especiales. Entre los smbolos especiales se encuentran:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

16

# ;

% <

& >

) ?

* [

, ]

+ ^

. }

/ |

Un comentario para una lnea comienza con la secuencia //. Para un bloque comienza con la secuencia /* y debe terminar con la secuencia */. Las secuencias de escape son cadenas que constan del smbolo \ y de letras caracteres especiales y permiten ejecutar alguna accin dentro del programa. o

Algunas de las secuencias de escape ms importantes son las mostradas en el cuadro 1. Cuadro 1. Secuencias de Escape Secuencia \a \b \n \r \t \v \ \ \? 1.2.2. Libreras Caracter Alerta Backspace Nueva lnea Retorno de carro Tabulador horizontal Tabulador vertical Apstrofo Comillas Interrogacin

En el Ejemplo 1 se llaman las libreras:

#include <stdio.h> #include <conio.h> #include <iostream.h>


Estas libreras son archivos de cabecera en el cual se encuentran declarados los prototipos de las funciones y macros que se utilizan dentro de un programa. Existe un extenso grupo de archivos de cabecera, y cada uno de ellos sirve para manejar un grupo de funciones relacionadas. La extensin h corresponde a la inicial de la palabra header que significa encabezado.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

17

La sintaxis para declarar una librera es: #include <nombrelibrera.extensin> Las libreras ms utilizadas son: stdio.h conio.h iostream.h graphics.h math.h librera estndar de entrada/salida librera de funciones de entrada/salida por consola librera de funciones de entrada/salida estndar de C++ librera de funciones grficas librera que contiene funciones matemticas

1.2.3.

Directivas

Tambin llamadas directivas del preprocesador y comienzan con el smbolo #, stas permiten ejecutar ciertas rdenes del preprocesador, o programa que contiene el compilador de C++ y que se ejecuta al iniciar la compilacin. La directiva #include permite incluir los contenidos de otros archivos de texto que contenga cdigo en C++ dentro del archivo. La directiva #define permite sustituir (antes de efectuar la compilacin) cada una de las ocurrencias de cierta cadena (llamada constante simblica) por otra cadena equivalente. Las directivas del preprocesador, permiten controlar cuales partes del cdigo fuente se van a compilar al cumplirse ciertas condiciones, algunas de estas son: #if, #ifdef, #if defined(algo), #ifndef, #else, #elif, #endif, #error, #pragma inline, #pragma warn, #pragma saveregs

1.2.4.

Variables

Una variable es un espacio de memoria que almacena informacin de algn tipo de dato y que cambia durante la ejecucin del programa. Es decir, una variable almacena un valor de tipo numrico o de tipo caracter como se observa en la Figura 1.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

18

Figura 1. Variable almacenada en memoria Memoria


Variable de tipo numrico

Identificador de variable: Es el nombre que se coloca a una variable. Los identificadores de las variables se caracterizan porque no pueden contener espacios en blanco, deben empezar con una letra y no con un dgito, no pueden tener caracteres especiales como tildes, comas, puntos, entre otros, exceptuando el smbolo de subrayado _ para concatenar o unir dos o mas palabras, o para comenzar el identificador. Los identificadores si aceptan dgitos numricos de 0 a 9 y los caracteres pueden estar en letras maysculas y minsculas. El tamao de un identificador de variable puede ser arbitrario, pero esto depende del compilador. Por ejemplo, el compilador de Borland C++ toma los primeros 32 caracteres como significativos. C++ hace diferenciacin entre minsculas y maysculas, por lo que el lenguaje tomar una variable minscula diferente a una mayscula, es decir la variable cuyo identificador es suma ser diferente al identificador de variable SUMA. No pueden ser identificadores de variables las palabras reservadas o propias del lenguaje. Algunas de estas palabras reservadas del lenguaje C estndar y C++ son las siguientes:

_asm _ds int _seg else _interrupt short auto enum interrupt signed break _es _loadds sizeof case _export long _ss _cdecl extern _near static cdecl _far near struct char far new switch class _fastcall operator template const float _pascal this continue for pascal typedef _cs friend private union default goto protected unsigned delete _huge public virtual do huge register void double if return volatile inline _saveregs while

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

19

1.2.5.

Constantes

Las constantes son espacios de memoria que almacenan un valor fijo durante todo el programa. Las constantes pueden ser de tipo entero, flotante, carcter y enumerado. La sintaxis para definir una constante es la siguiente:

Por ejemplo, la constante pi se define as:

const Nombre_Constante = valor;

const pi = 3,1415;
Una constante, se puede declarar en cualquier parte del programa, inclusive se puede declarar, en la lista de parmetros de una funcin y en archivos de cabecera.

1.3.

TIPOS DE DATOS

Dependiendo del tipo de dato, la variable puede ocupar ms o menos espacio en memoria. Es decir, cada tipo de dato tiene asignado un tamao especfico de memoria para cada una de las variables. En C++, se pueden utilizar los tipos de datos propios del lenguaje o se pueden crear tipos de datos personalizados con las palabras reservadas enum, struct y union.

1.3.1.

Tipos de datos Numricos

Se refieren a variables que almacenan valores numricos y principalmente pueden ser de tipo entero y de tipo real. Enteros: Se refieren a valores que no tienen parte decimal. El tamao y el rango de valores de los diversos tipos de datos entero se observan en el cuadro 2 y 3. Cuadro 2. Tipos de datos entero 16 bits Tipo de dato Short int Int Tamao 16 bits 16 bits Rango -32,768 -32,768

a a

32,767 32,767

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

20

Int Sin signo 16 bits Long 32 bits Long Sin signo 32 bits Cuadro 3. Tipos de datos entero 32 bits Tipo de dato Short int Int Int Sin signo Long Long Sin signo Tamao 16 bits 32 bits 32 bits 32 bits 32 bits

0 a 65,535 -2,147,483,648 a 2,147,483,647 0 a 4,294,967,295

Rango -32,768 a 32,767 -2,147,483,648 a 2,147,483,647 0 a 4,294,967,295 -2,147,483,648 a 2,147,483,647 0 a 4,294,967,295

Decimales: Se refieren a valores que tienen parte decimal. El tamao y el rango de valores de los diversos tipos de datos real o flotante se observan en el cuadro 4. Cuadro 4. Tipos de datos decimal 16 y 32 bits Tipo de dato float double long double Tamao 32 bits 64 bits 80 bits Rango 3.4 x 10-38 a 3.4 x 10+38 (7 dgitos de precisin) 1.7 x 10-308 a 1.7 x 10+308 (15 dgitos de precisin) 3.4 x 10-4932 a 1.1 x 10+4932 (18 dgitos de precisin)

1.3.2.

Tipos de datos Caracter

Se refieren a variables que almacenan un carcter alfanumrico. En C++ no existe la cadena de caracteres, por lo que se debe crear un vector de caracteres, para simular una cadena. El tamao y el rango de valores de los diversos tipos de datos caracter se observan en el cuadro 5.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

21

Cuadro 5. Tipos de datos carcter 16 y 32 bits. Tipo de dato Char Tamao 8 bits Rango -128 a 127 (nmeros muy pequeos y caracteres ASCII) 0 a 255 (nmeros pequeos y conjunto completo de caracteres del PC)

Char sin signo

8 bits

Enumerados: Son tipos de datos que constan de uno o ms valores. La sintaxis es la siguiente:

enum nombre_enumerado {valor1, valor2, valor3, ..,valor n} ;


Un ejemplo de enumerado pueden ser los das de la semana:

enum dias {lunes, martes, mircoles, jueves, viernes } ;


Declaracin de variables: Las variables en C++ se declaran teniendo en cuenta la siguiente sintaxis:

Tipo_de_datos
Un ejemplo de variable de tipo entero:

nombre_variable;

long int cedula;


Un ejemplo de variable de tipo caracter:

char letra;
Si se declara ms de una variable, stas se deben colocar consecutivamente una tras otra, separadas por comas. As:

float num1, z, d, num2;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

22

1.4.

LECTURA Y ESCRITURA EN C++

En C++ existen funciones de lectura y escritura declaradas en las libreras stdio.h, conio.h, iostream.h. 1.4.1. Librera stdio.h

Stdio.h es la librera estndar de entrada y salida. Entre las funciones de lectura y escritura de la librera stdio.h se encuentran scanf, printf, gets y puts. scanf: funcin perteneciente a la librera stdio.h. Permite capturar de teclado un valor y lo permite almacenar dentro de una variable. El formato de scanf es:

scanf (<cadena de formato>, direccin_variable1, direccin_variable2, .... direccin_variablen);


La cadena de formato consta del operador %, seguido del tipo de dato de la variable y se encuentra encerrada entre comillas dobles. Por otra parte, la direccin de la variable se denota anteponiendo a la variable el smbolo &. Su sintaxis es la siguiente:

%tipo_de_dato
Por ejemplo, si a es una variable de tipo entero, la lectura de dicha variable se realiza de la siguiente forma:

scanf(%d, &a);
Los tipos de datos que le pueden anteceder a % se observan en el cuadro 6: Cuadro 6. Tipos de datos que preceden % Comando Sirve para

%d

Entero

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

23

%u %ld %p %f %e %c %s %x %o

entero sin signo entero largo Valor de apuntador nmero de punto flotante nmero de punto flotante en valor exponencial Carcter cadena de caracteres entero en formato hexadecimal entero en formato octal

printf: funcin perteneciente a la librera stdio.h. Permite imprimir en pantalla el valor de una variable. El formato de printf es:

printf (<cadena de formato>, variable 1, variable 2, ...., variable n);


La cadena de formato encerrada entre comillas dobles consta de una cadena de caracteres (mensajes) y de los argumentos correspondientes a las variables que se desean mostrar en pantalla. Esta cadena es enviada a la pantalla despus de haber sustituido los elementos listados despus de la cadena. La sustitucin de los elementos se hace de acuerdo a los comandos de formato incluidos en cadena_formato, los cuales empiezan con el smbolo por ciento (%). Por ejemplo, para imprimir el valor de la variable utilidad de tipo entero se utiliza la siguiente lnea:

printf("La utilidad es del %2d %\n", utilidad);


gets y puts: Las funciones gets y puts estn declaradas en la librera stdio.h. La funcin gets captura el valor de una cadena de teclado y se almacena en la variable que aparece en el argumento de la funcin gets. La funcin puts imprime en pantalla el valor de dicha variable de tipo cadena. En el ejemplo, se declara una variable de tipo cadena llamada nombre y se captura un valor con gets y se imprime su valor con puts.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

24

Ejemplo 2. Programa que usa gets y puts

#include <stdio.h> #include <conio.h> void main() {char nombre[5]; printf("su nombre es: \n"); gets(nombre); printf("el nombre que acaba de digitar es:\t"); puts(nombre); getch(); }
1.4.2. Librera conio.h

Conio.h es la librera de entrada y salida de consola. Entre las funciones de lectura y escritura de la librera conio.h se encuentran getch() y getche(). getch(): funcin declarada en la librera conio.h. La funcin captura un caracter de la pantalla pero no lo imprime en pantalla. getche(): funcin declarada en la librera conio.h. La funcin getche() al igual que getch() captura un caracter sin embargo, esta si la imprime en pantalla.

1.4.3. Librera iostream.h Otras funciones de lectura y escritura muy utilizadas en C++ son cin y cout. Para utilizar estas funciones se necesita usar la librera iostream.h. cin: El objeto cin utiliza al operador sobrecargado >> para capturar los datos desde el teclado. cout: El objeto cout utiliza al operador sobrecargado << para enviar datos hacia la pantalla.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

25

1.5.

ESTRUCTURAS DE CONTROL

Las instrucciones en un programa en C++ se ejecutan de arriba hacia abajo y estn formadas por una o varias expresiones simples colocadas una a continuacin de la otra. Las instrucciones estructuradas, tienen la siguiente sintaxis:

Instruccin Instruccin Instruccin Instruccin ..... Instruccin

1 2 3 4 N

1.5.1.

Asignaciones

Una asignacin es una instruccin simple que permite asignar un valor (miembro derecho), a una variable (miembro izquierdo). La sintaxis de una instruccin estndar de asignacin es:

Variable = valor;
Por ejemplo,

Precio = 5000;
Esto quiere decir que, se asigna el valor de 5000 a la variable precio. En una asignacin el miembro derecho, no necesariamente es un valor, tambin puede ser una expresin aritmtica de la forma:

Variable = expresin_aritmtica;
Las expresiones aritmticas estn formadas por un conjunto de nmeros, variables y funciones relacionadas con los operadores del lenguaje. Por ejemplo, en una asignacin de la forma:

x = x + 1;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

26

Primero, se evala el lado derecho, y posteriormente el valor resultante se asigna a la variable del lado izquierdo. Es decir, si x antes de la asignacin tiene el valor de 4, y se ejecuta dicha instruccin, inicialmente se realiza 4 + 1 cuyo resultado es 5 y luego este valor es almacenado en la variable x, quedando finalmente, la variable x con el valor de 5. Las asignaciones en C++ se pueden colocar en las declaraciones de las variables. En el lenguaje C++ no existe un fuerte chequeo de tipos de datos y existen diferentes formas de realizar una asignacin. Sin embargo, no se puede abusar de dicha flexibilidad. Operadores aritmticos: Los operadores que se utilizan en una expresin aritmtica se muestran en el cuadro 7: Cuadro 7. Operadores aritmticos Operador + * / Operacin Suma Resta Multiplicacin Divisin entera si los operandos son enteros, y divisin real si al menos uno de ellos es flotante Mdulo o resto Incremento Decremento

% ++ --

En C++ se pueden realizar asignaciones diferentes a la estndar, como se observa en el cuadro 8: Cuadro 8. Asignaciones no convencionales Operador += -= *= /= %= Expresin x += 1 equivalente a x = x + 1 x -= 1 equivalente a x = x - 1 x *= 1 equivalente a x = x * 1 x /= 2 equivalente a x = x / 2 x %= 1 equivalente a x = x % 1

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

27

1.5.2.

Estructuras condicionales

Las estructuras condicionales estn formadas por los condicionales de dos opciones y los condicionales mltiples y ambos mediante una comparacin permiten seleccionar una opcin de una, dos o varias alternativas. Condicional de dos opciones: El condicional permite seleccionar una de dos opciones, teniendo en cuenta una condicin. En la figura 2 si la condicin se cumple, se ejecuta el proceso 1, de lo contrario, se ejecuta el proceso 2. Figura 2. Condicional 2 opciones

Condicin

Proceso 2

Proceso 1

La condicin es una comparacin que se realiza entre una variable al lado izquierdo y un valor, variable o expresin aritmtica al lado derecho y sigue la sintaxis: Variable (operador relacional) valor Variable (operador relacional) variable Variable (operador relacional) expresin aritmtica Operadores Relacionales: se utilizan para comparar los valores que resultan de reducir los valores. Como se observa en el cuadro 9:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

28

Cuadro 9. Operadores relacionales Operador relacional > < >= <= == != Por ejemplo, Precio > 200000 Precio_menor < precio Precio_menor < Preciomenor * 1.5 En C++ el condicional de dos opciones sigue la sintaxis: Significado Mayor que Menor que Mayor o igual que Menor o igual que Igual que Diferente que

If (condicin) { proceso1 } else { proceso2 }


Adems, se pueden anidar condicionales de dos opciones, unos dentro de otros, para elegir entre un grupo de ms de dos opciones, as:

If (condicion1) { If (condicion2) {proceso2} else { If (condicion3) { proceso3} else {proceso4} }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

29

} else

. . .

{procesoN}

Una condicin no solo est formada por operadores relacionales, tambin, puede incluirse operadores lgicos. Operadores lgicos: Los operadores lgicos se aplican sobre enunciados que resultan de las operaciones relacionales y el resultado siempre ser un valor de verdad, como se observa en el cuadro 10: Cuadro 10. Operadores lgicos Operador && || ! Significado Y (conjuncin) O (Disyuncin) No (Negacin)

Por ejemplo, una condicin utilizando operadores relacionales y operadores lgicos puede ser: (n>1) | | (n > 30) Condicional Mltiple: El condicional mltiple de la figura 3 permite seleccionar una de mltiples opciones dependiendo del valor de una variable de tipo entero. Si la variable toma el valor 1 se ejecuta el proceso 1, si la variable toma el valor 2 se ejecuta el proceso 2, y as sucesivamente. Figura 3. Condicional mltiple
variable

Valor 1 Proceso 1

Valor 2 Proceso 2

Valor 3 Proceso 3

Valor N Proceso N

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

30

La sintaxis del condicional mltiple en C++ es la siguiente:

switch(variable) { case valor_1 : Bloque_1; break ; case valor_2 : Bloque_2; break ; . case valort_N : Bloque_N; break ; default : Bloque_X ;break; }

1.5.3.

Estructuras iterativas

Instruccin For: Esta instruccin se utiliza cuando se sabe exactamente el nmero de veces que se debe repetir el proceso. Un for se puede representar grficamente como se indica en la Figura 4: Figura 4. Instruccin For.

Inicializacin, condicin, incremento

Proceso

La inicializacin en el for es una instruccin que permite declarar e inicializar la variable que se utiliza para llevar el nmero de cuenta del proceso que se va a ejecutar. La condicin se utiliza para detener el ciclo repetitivo. El incremento es una instruccin que aumenta en una cantidad constante la variable que cuenta los procesos.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

31

Figura 5. Ejemplo Instruccin For.

i = 0; i < n;

i ++

Proceso

En la figura 5 se muestra la estructura iterativa, en la cual se repite el proceso desde 0 veces hasta n-1 veces, incrementndose la variable de 1 en 1. En el lenguaje C++ esta instruccin sigue la sintaxis:

for (inicializacin; condicin; incremento) {bloque de instrucciones }


Instruccin While: esta instruccin permite repetir un proceso varias veces, mientras la condicin sea verdadera. Si la condicin es falsa, se detiene el proceso iterativo y se sale del while. La figura 6 permite ver un while: Figura 6. Instruccin While.
condicin

Proceso

while (condicin) { bloque de instrucciones }

La sintaxis en C++ de un while es:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

32

Instruccin do while: esta instruccin primero ejecuta el proceso, y luego evala la condicin. Si la condicin es falsa, se detiene el proceso iterativo y se sale del do while. La figura 7 permite ver un do while: Figura 7. Instruccin do while
Proceso

condicin

La sintaxis en C++ de un do while es:

do { bloque de instrucciones } while (condicin);


Ejercicios seccin 1.5. 1.5.1. Realice un programa que encuentre el valor aproximado del coseno de un nmero x utilizando las series de Taylor. 1.5.2. Realizar un programa que utilizando un men con opciones calcule el rea de : 1. 2. 3. 4. Tringulo Cuadrado Crculo Salir del men

1.5.3. Escribir un programa que calcule la nmina de N trabajadores de la manera siguiente. El trabajador cobra un precio fijo por hora y se le retiene un 5%. El programa debe solicitar el nombre de los trabajadores, las horas trabajadas de cada uno y el precio que cobra por hora. Como salida debe imprimir el sueldo bruto, la retencin y el sueldo neto.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

33

1.5.4. Escribir un programa que dados dos nmeros, uno real (base) y un entero positivo (exponente), imprima en pantalla todas las potencias con base el nmero dado y exponentes entre uno y el exponente introducido. 1.5.5. Escribir un programa que, solicite la fecha de nacimiento de una persona e imprima por pantalla su signo zodiacal.

1.6.

FUNCIONES

Una funcin es un conjunto de instrucciones dentro del programa que ejecutan una serie de acciones y que puede ser llamada desde el programa principal, llamarse a s misma o desde otra funcin. La funciones pueden retornar o no un nico valor al programa principal.

1.6.1.

Funciones que no retornan un nico valor

La sintaxis de una funcin que no retorna un nico valor es: VOID nombre_de_la_funcin (lista_de_parmetros) { return; } Llamado de la funcin en el programa principal: Se llama la funcin nicamente con el nombre, sin necesidad de hacer ninguna asignacin, adems se deben indicar los parmetros o valores de entrada a la funcin, as: Nombre_de_la_funcin (parmetros); Un ejemplo de funcin void o que no retorna un nico valor al programa principal es:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

34

Ejemplo 3. Funcin de tipo void #include <stdio.h> #include <conio.h> #include <iostream.h> void factorial(int x) {long int f; int i; f = 1; if (x > 1) {for (i = 1; i <= x; i++ ) f = f * i;} else if (x == 1) f = 1; cout<<"el factorial de "<<x<<" es: "<<f; return; } void main() {int a; cout<<"digite un numero\n"; cin>>a; factorial(a); getch(); }

1.6.2.

Funciones que retornan un nico valor

La sintaxis de una funcin que devuelve un nico valor al programa principal es:

TIPODEDATOS nombre_de_la_funcin (lista_de_parmetros) { return(variable); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

35

Llamado de la funcin en el programa principal: Se llama la funcin utilizando una expresin o asignacin. Adems se deben indicar los parmetros o valores de entrada a la funcin. Z = Nombre_de_la_funcin (parmetros); Un ejemplo de funcin que retorna un nico valor al programa principal es: Ejemplo 4. Funcin que retorna un nico valor #include <stdio.h> #include <conio.h> #include <iostream.h> long int factorial(int x) { long int f; int i; f = 1; if (x > 1) {for (i = 1; i <= x; i ++ ) f = f * i; } else if (x == 1) f = 1; return(f); } void main() { int a; long int fact; cout<<"digite un numero\n"; cin>>a; fact = factorial(a); cout<<"el factorial es :"<<fact; getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

36

1.6.3.

Paso de parmetros por valor

Los valores dentro del programa principal se conservan, nicamente se cambian dentro de la funcin llamadora.

1.6.4.

Paso de parmetros por referencia

Los valores no se conservan dentro del programa principal, es decir, las modificaciones o alteraciones de las variables dentro de la funcin llamadora retornan de nuevo al programa principal pero con valores transformados por dicha funcin. Un ejemplo de funcin con paso de parmetros por valor y por referencia es: Ejemplo 5. Funcin con paso de parmetros por valor y referencia #include <stdio.h> #include <conio.h> #include <iostream.h> void funcion1(int v) { v = 4; cout<<"el valor de v dentro de la funcion 1 es : "<< v <<"\n"; return;} void funcion2(int *pv) { *pv = 4; cout<<"el valor de v dentro de la funcion 2 es : "<< *pv<<"\n"; return;} void main() {int v = 3, *pv; pv = &v; cout<<"el valor de v antes de la funcion 1 es: "<< v <<"\n"; funcion1(v); cout<<"el valor de v despues de la funcion 1 es: "<< v <<"\n"; cout<<"el valor de v antes de la funcion 2 es: "<< v <<"\n"; funcion2(pv);

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

37

cout<<"el valor de v despues de la funcion 2 es: "<< v <<"\n"; getch(); }

1.6.5. Sobrecarga de Funciones

Existe sobrecarga de funciones en C++, cuando se definen 2 o ms funciones con el mismo nombre pero los parmetros son de diferente tipo de dato. Esta capacidad se llama homonimia de funciones. Estas son usadas para que ejecuten tareas diferentes pero sobre tipos de datos diferentes. A continuacin, se muestra un ejemplo de sobrecarga de funciones. La funcin menor identifica de dos valores cul es el nmero menor y as mismo cul de dos letras es la menor en el alfabeto. Ejemplo 6. Sobrecarga de funciones #include <iostream.h> #include <conio.h> int menor ( int a, int b) { if (a < b) return (a); else return (b); } char menor(char a, char b) { if (a < b) return (a); else return (b); } void main() { int x,y,nummen; char m, n, nommen; cout<<"digite el primer numero: ";

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

38

cin>>x; cout<<"\ndigite el segundo numero: "; cin>>y; nummen = menor(x,y); cout <<"el nmero menor es: "<<nummen; cout<<"\ndigite una letra: "; cin>>m; cout<<"\ndigite otra letra: "; cin>>n; nommen = menor(m,n); cout <<"\nla letra menor en el alfabeto es: "<<nommen; getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

39

2. ESTRUCTURAS DE DATOS ESTTICAS

2.1. 2.2. 2.3.

VECTORES MATRICES REGISTROS

Las estructuras estticas son aquellas que ocupan un espacio en la parte baja de la memoria (puede ser en el segmento de datos) de manera constante durante la ejecucin de un programa. Dentro de las principales estructuras estticas estn los arreglos unidimensionales o multidimensionales estticos, los registros y los archivos.

2.1.

VECTORES

2.1.1.

Definicin de vector

Los vectores son espacios unidimensionales de memoria que almacenan informacin de un mismo tipo de datos. Tambin son conocidos como arreglos o conjuntos de celdas. Un vector se representa como se indica en la figura 8: Figura 8. Representacin grfica de un vector

Vector A
Posicin 0 Posicin 1 Posicin 2

Posicin N

4 5 7 9 . . . 6

Los vectores constan de un nombre y de un tamao dado por el conjunto de celdas que contiene el vector. Los nombres de los vectores tienen las mismas caractersticas

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

40

de los identificadores de variables. Cada celda tiene una posicin dentro del vector, y esta se indica utilizando una variable. Por ejemplo, si i = 1 se est indicando la celda ubicada en la posicin 1 que corresponde a la segunda celda ya que i comienza en 0. Si se desea referenciar el contenido de cada celda la sintaxis es la siguiente: Nombre_del_vector [Posicin de la celda] Por ejemplo, si se desea saber qu contiene la celda ubicada en la posicin 2 se usa: A[ 2 ] Por supuesto, ubicando esta parte de cdigo en una instruccin de escritura dara como resultado en pantalla el valor de 7. Entonces, si se desea referenciar una celda ubicada en cualquier posicin del vector se utiliza: A[ i ]

2.1.2.

Actividades en Vectores

En los vectores se pueden realizar tres actividades: Lectura o almacenamiento de la informacin, recorrido, e impresin o escritura de un vector. Lectura de un vector: Para leer o almacenar la informacin en un vector se utiliza una instruccin for que requiere de una variable que indica la posicin de cada celda en el vector. La figura 9 indica como se almacena informacin en un vector: Figura 9. Lectura o almacenamiento de informacin en un vector.

i =0;

i < n ; i++

A[ i ]

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

41

Un ejemplo de lectura de un vector en lenguaje C++ es: Ejemplo 7. Lectura de un vector for (i=0;i<5;i++) { cout<<"digite un numero entero\n"; cin>>A[i]; } Recorrido de un vector: Para recorrer las celdas de un vector con el fin de realizar algn clculo con el contenido del vector o realizar algn proceso diferente a leer o escribir tambin se utiliza, como en el caso anterior, solo una instruccin for. La figura 10 indica como se recorre un vector:

Figura 10. Recorrido en un vector.

i =0;

i < n ; i++

Proceso (A[i])

Un ejemplo de recorrido de un vector en lenguaje C++ es: Ejemplo 8. Recorrido de un vector for (i=0;i<5;i++) { B[i+1] = A[i] * 2 ; } Escritura de un vector: Para escribir el contenido de un vector en pantalla se utiliza un for para recorrer cada una de las celdas del vector. La figura 11 indica como se imprime en pantalla el contenido de un vector:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

42

Figura 11. Impresin de un vector.


i =0; i < n ; i++

A[i]

Un ejemplo de impresin de un vector en lenguaje C++ es: Ejemplo 9. Impresin de un vector for (i=0;i<5;i++) { cout<<A[i]<<\n ; } Ejercicios seccin 2.1.2. 2.1.2.1. Una persona decide ahorrar una cantidad fija de dinero cada mes durante n aos. Si el dinero est a un inters i por ciento anual, se desea saber cunto dinero se tiene dentro de n aos. La cantidad futura se determina como: F = A * [ei*n 1 / e
i/12

1]

Si se tiene un vector X con diferentes valores de inters desde 1% (0,01) hasta el 20% (0,2). Se desea obtener el vector Y con el valor futuro si A = 100 y el nmero de aos es 3. 2.1.2.2. Escribir un programa que genere un vector Y que contenga los valores para la ecuacin: Y = 2 * e 0.1 * t * Sen (0,5*t) A partir de un vector T que contenga los valores del tiempo, los cuales varan entre 0 y 10. 2.1.2.3. Si se tiene un vector llamado P con los pesos en Kgs. de los pacientes de la oficina de control en nutricin. Encontrar la media y la desviacin estndar de los pesos de los pacientes. Se tiene un vector COD con los cdigos de los N estudiantes y cuatro

2.1.2.4.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

43

vectores ms N1, N2, N3 y N4 con las notas parciales de una asignatura. Hallar: Un vector DEF con las definitivas de los N estudiantes. Imprimir el listado ordenado de mayor a menor teniendo en cuenta las notas definitivas. Imprimir el cdigo del estudiante que obtuvo mayor y menor definitiva 2.1.2.5. Se tiene un vector M con los nmeros del 1 al 12 que indica los meses del ao. Adems se tiene un vector PRODUCTOS con la cantidad de unidades de ese producto vendidos en cada mes. Si se cuenta con un vector PRECIO que indica la variacin del precio mes a mes. Hallar:

El promedio de ventas anual. Un vector VENTAS con lo vendido en cada mes. Si se tiene un vector GASTOS hallar la utilidad mensual. Imprimir el mes con menor utilidad y mayor utilidad. Se tiene el histrico de notas de un estudiante de un programa determinado de UNISANGIL con la siguiente informacin: nmero de crditos cdigo de la materia nota definitiva semestre

2.1.2.6.

Cada dato se encuentra en un vector. El director del programa desea saber: Promedio aritmtico Promedio ponderado Nmero de materias aprobadas y no aprobadas Listado de materias ordenada ascendentemente por nota definitiva Cdigo de la materia con mayor nota y cdigo de la materia con menor nota definitiva. 2.1.2.7. Dado un vector lleno, a cada elemento restarle el anterior e imprimir el resultado en pantalla (al primero se le debe restar el ltimo elemento). Implementar un programa que diga si un nmero es capica. Utilice un vector para resolver el problema.

2.1.2.8.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

44

2.1.2.9.

Dado un vector, implementar un programa que inserte un elemento en una posicin dada del vector.

NOTA: Insertar un elemento en el vector desplaza una posicin hacia la derecha a los elementos del vector que han de quedar detrs del elemento insertado. Adems, la insercin ocasiona la desaparicin del ltimo elemento del vector. 2.1.2.10. Dado un vector de nmeros reales, implemente un programa que ordene los elementos del vector de tal forma que los nmeros pares aparezcan antes que los nmeros impares. Adems, los nmeros pares debern estar ordenados de forma ascendente, mientras que los nmeros impares debern estar ordenados de forma descendente. Esto es, el vector {1,2,3,4,5,6} quedar como {2,4,6,5,3,1}.

2.2.

MATRICES

2.2.1.

Definicin de matriz

Una matriz es un espacio bidimensional de memoria que almacena informacin de un mismo tipo de dato. Una matriz se representa grficamente como un conjunto de filas y un conjunto de columnas, en donde la interseccin de una fila y una columna corresponde a una celda. Una matriz tiene un nombre y un tamao. El nombre es un identificador de variable y el tamao es la cantidad de celdas de la matriz y para calcularlo basta con multiplicar el nmero de filas por el nmero de columnas. Es decir, si una matriz tiene 12 filas y 10 columnas su tamao es 12 x 10 = 120 celdas. Grficamente una matriz se representa como se indica en la figura 12:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

45

Figura 12. Representacin grfica de una matriz

Matriz A columna 0 columna 1 Fila 0 Fila 1 Fila 2


4 5 7 9 . . . . . 6 5 7 8 2 . . . . . 4 ... ... ... ... . . . . . 3

columna M
1 5 8 9 . . . . . 5

Fila N

Si se desea referenciar el contenido de una celda de la matriz la sintaxis es la siguiente: Nombre_de_la_matriz [Posicin de la fila] [Posicin de la columna] Por ejemplo, si se desea saber qu contiene la celda ubicada en la fila 2 columna 1 se utiliza: A[ 2 ][ 1 ] Si se ubica esta parte de cdigo en una instruccin de escritura dara como resultado en pantalla el valor de 8. Si se desea referenciar cualquier celda de la matriz se utiliza: A[ i ][ j ] 2.2.2. Actividades en Matrices

En las matrices se pueden realizar tres actividades: Lectura o almacenamiento de la informacin, recorrido, e impresin o escritura de una matriz.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

46

Lectura o almacenamiento de la informacin en una matriz: Para leer una matriz se necesita utilizar dos indicadores o variables. La primera, por ejemplo i, indica el nmero de fila y la segunda, por ejemplo j, indica el nmero de la columna. La figura 13 representa la lectura de una matriz: Figura 13. Lectura de una matriz
i =0; i < N ; i++

j =0;

j < M ; j++

A[ i ][j]

Un ejemplo de lectura de una matriz en el lenguaje C++ es: Ejemplo 10. Lectura de matrices for (i=0;i<5;i++) { for (j=0;j<5; j++) { cout<<"digite un numero entero\n"; cin>>A[i][j]; } } Recorrido de una matriz: Al igual que en la lectura, recorrer una matriz necesita de dos instrucciones for. La figura 14 representa el recorrido de una matriz: Figura 14. Recorrido de una matriz
i =0; i < N ; i++

j =0;

j < M ; j++

Proceso(A[ i ][j])

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

47

Un ejemplo de recorrido de una matriz en el lenguaje C++ es: Ejemplo 11. Recorrido de matrices for (i=0;i<5;i++) { for (j=0;j<5; j++) { if (i == j) A[i][j] = 1; //pone en 1 la diagonal principal } } Escritura de una matriz: Para escribir el contenido de una matriz en pantalla se usa un for que recorre las filas i y un for que recorre las columnas j. La figura 15 representa la escritura en pantalla de una matriz: Figura 15. Escritura de una matriz
i =0; i < N ; i++

j =0;

j < M ; j++

A[ i ][j]

Un ejemplo de escritura de una matriz en el lenguaje C++ es: Ejemplo 12. Impresin de una matriz for (i=0;i<5;i++) { for (j=0;j<5; j++) { cout<<A[i][j]<<"\t"; } cout<<"\n"; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

48

Un programa sencillo en consola que lee una matriz y la imprime en pantalla es: Ejemplo 13. Programa sencillo de matrices # include<stdio.h> # include<conio.h> # include<iostream.h> void main() { int m[5][5],i,j; for (i=0;i<5;i++) { for (j=0;j<5; j++) { cout<<"digite un numero entero\n"; cin>>m[i][j]; } } for (i=0;i<5;i++) { for (j=0;j<5; j++) { cout<<m[i][j]<<"\t"; } cout<<"\n"; } getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

49

Ejercicios Seccin 2.2.2.


2.2.2.1. Hacer un programa que realice las siguientes matrices: 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 1 1 1 1 1 1 1 1 1

2.2.2.2. Si se tiene la informacin de una aerolnea que consta de: Cantidad de pasajeros en 5 rutas comerciales durante los 30 del mes de marzo. Se desea saber el promedio de pasajeros durante cada da del mes, y el promedio de pasajeros de cada ruta durante los 30 das del mes. Utilice matrices. 2.2.2.3. El producto de dos matrices con elementos A(I,J) y B(I,J) es una tercera matriz con elementos. C(I,J)= A(I,J) B(I,J) + ... + A(I,N) B(N,J) Suponiendo que el nmero de columnas de la matriz A y el nmero de filas de la matriz B son ambos igual a N. Elaborar un programa que calcule el producto de matrices. 2.2.2.4. Inventario de una red de almacenes Se debe hacer una vez al ao un inventario valorizado (en pesos) del stock de piezas de aluminio que hay en los almacenes de una metalmecnica. Se sabe que la industria cuenta con M almacenes y N piezas. Se solicita desarrollar un programa que: Llene la matriz INV de M x N, donde (M representa las filas / almacenes) y (N representa las columnas / piezas) y un vector P de costos de N elementos con los precios de las piezas. Calcule:

Valor total en pesos de cada uno de los almacenes. Valor en pesos de cada una de las piezas. Total general en pesos. Indicar almacn y pieza con stock cero.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

50

2.3.

REGISTROS

Un registro es un conjunto de campos, cada uno de los cuales permite almacenar informacin de diferente tipo de datos. Un registro se representa grficamente como se indica en la figura 16. Figura 16. Registro Campo 1 Dato 1 Campo 2 Dato 2 Campo 3 Dato 3 .... Campo N Dato N

2.3.1.

Definicin de un registro

En C++ existen varias formas de definir un registro: typedef struct {lista_de_campos} nombre_estructura; struct nombre_estructura {lista de campos};

Por ejemplo: struct estudiante {int codigo; char nombre[50], apellidos[50], carrera[50]; float promedio;}; Este registro se representa grficamente como se indica en la figura 17. Figura 17. Registro estudiante codigo nombre 20110354 Jorge

apellidos Prez

carrera Contadura

promedio 4.15

2.3.2.

Declaracin de variables registros

Para declarar un registro se coloca primero el tipo de datos y luego la lista de variables de tipo registro. La sintaxis de la declaracin de un registro es:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

51

Tipo_registro nombre_registro1, nombre_registro2...nombre_registroN; Un ejemplo puede ser: estudiante estudiante1, estudiante2; Un programa de lectura y escritura de un registro puede ser: Ejemplo 14. Registros #include <conio.h> #include <stdio.h> #include <iostream.h>

void main() { struct estudiante{ int codigo; char nombre[10];}; estudiante est; cout<<"digite el codigo de un estudiante\n"; cin>>est.codigo; cout<<"digite el nombre de un estudiante\n"; cin>>est.nombre; cout <<"codigo:"<<est.codigo<<"\t nombre:"<<est.nombre; getch(); } Ejemplo 15. Registro de un estudiante Crear el registro de un estudiante con la informacin cdigo del estudiante, nombre y cdigo de la carrera, utilizando un struct. #include <stdio.h> #include <conio.h> #include <iostream.h> struct estudiante

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

52

{ char nombre[20]; int codigo; int carrera; }; estudiante est; void main() { cout <<"digite el nombre"<<"\n"; cin >> est.nombre; cout <<"digite el codigo"<<"\n"; cin >> est.codigo; cout <<"digite la ambiental)"<<"\n"; cin >> est.carrera; carrera (1 = ingeniera de sistemas 2= ingeniera

cout <<"el estudiante que acaba de ingresar es : "<<"\n"; cout <<"nombre: "<<est.nombre<<"\t"<<"codigo:"<< <<"carrera:"<<"\t"<<est.carrera<<"\n"; getch(); } 2.3.3. Arreglo de registros

est.codigo

Un arreglo de registros es un conjunto de registros dispuestos en un vector. La declaracin de un arreglo de registros tiene la sintaxis: Tipo_registro nombrevector[cantidad de registros]; Por ejemplo, un arreglo de registros que contiene la informacin de 20 estudiantes de un aula de clase es: Estudiante listaclase[20];

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

53

Ejemplo 16. Arreglo de registros Crear y almacenar una lista de N estudiantes de un aula de clase. Ordenar la lista teniendo en cuenta el cdigo del estudiante. La lista es un arreglo de registros. #include <stdio.h> #include <conio.h> #include <iostream.h> struct estudiante { char nombre[20]; int codigo; int carrera; }; int i,j, n ; estudiante est[100], temp; void main() { cout <<"digite la cantidad de estudiantes"<<"\n"; cin >> n; for (i=0; i<n; i++) { cout <<"digite el nombre"<<"\n"; cin >> est[i].nombre; cout <<"digite el codigo"<<"\n"; cin >> est[i].codigo; cout <<"digite la carrera (1 = ingeniera de sistemas 2 = ingeniera ambiental)"<<"\n"; cin >> est[i].carrera; } cout <<"listado de estudiantes "<<"\n"; for (i=0; i<n-1; i++) {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

54

for (j=i+1; j<n;j++) { if ( est[i].codigo > est[j].codigo) { temp = est[i]; est[i] = est[j]; est[j] = temp; } } } for (i=0; i<n; i++) { cout <<"nombre: "<<est[i].nombre<<"\t"<<"codigo:"<< <<"\t"<<"carrera:"<<est[i].carrera<<"\n"; } getch(); } Ejemplo 17. Archivo de una empresa Se tiene un archivo con informacin de las ventas diarias del primer trimestre del ao 2005 de tres sucursales de la empresa de calzado Milpies de Yopal. El archivo cuenta con los siguientes datos: cdigo de la sucursal (1 = Pereira 2= Cartagena 3= Bogot) nombre de la sucursal nmero del mes (1 = enero 2= febrero 3 = marzo) total de venta diaria El gerente desea tener el promedio de ventas de cada una de las sucursales del ao 2005. Adems desea tener el promedio de ventas de cada uno de los meses del primer trimestre del ao 2005. est[i].codigo

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

55

Construir un programa que genere los resultados solicitados por el gerente Milpies para el primer trimestre del 2005. Utilice para ello un struct y una matriz. #include <stdio.h> #include <conio.h> #include <iostream.h>

struct empresa { char nombre[20]; int codigo; int mes; float totalventa; }; int i, j, n ; float sumames=0, sumasuc=0, promsuc=0, prommes=0, matrizventas[3][3]; empresa ventas[100];

void main() { cout <<"digite la cantidad de registro de ventas diarias"<<"\n"; cin >> n; //se inicializa la matriz en cero for (i=0;i<3;i++) { for (j=0;j<3; j++) { matrizventas[i][j] = 0; } }; // se leen los datos del archivo de ventas diarias y se acumulan en la matriz for (i=0; i<n; i++) {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

56

cout <<"digite el nombre"<<"\n"; cin >> ventas[i].nombre; cout <<"digite el codigo de la sucursal 1= pereira 2= cartagena 3= bogota"<<"\n"; cin >> ventas[i].codigo; cout <<"digite el nmero del mes 1= enero 2= febrero 3 = marzo"<<"\n"; cin >> ventas[i].mes; cout <<"digite el total de la venta"<<"\n"; cin >> ventas[i].totalventa; matrizventas[ventas[i].codigo-1][ventas[i].mes-1] matrizventas[ventas[i].codigo-1][ventas[i].mes-1] + ventas[i].totalventa; } // se imprime la matriz de ventas cout <<"la matriz de ventas es : "<<"\n"; for (i=0;i<3;i++) { for (j=0;j<3; j++) { cout<<matrizventas[i][j]<<"\t" ; } cout<<"\n" ; }; =

cout <<"el promedio de cada sucursal : "<<"\n"; //se calcula promedio de ventas de cada sucursal for (i=0;i<3;i++) {sumasuc =0; for (j=0;j<3;j++) { sumasuc = sumasuc + matrizventas[i][j]; } promsuc = float(sumasuc)/3; cout <<"el promedio de la sucursal " << i+1 <<"es: "<<"\t"<<promsuc<<"\n"; };

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

57

cout <<"el promedio de cada mes : "<<"\n"; //se calcula promedio de ventas de cada mes for (j=0;j<3;j++) {sumames =0; for (i=0;i<3; i++) { sumames = sumames + matrizventas[i][j]; } prommes = float(sumames)/3; cout <<"el promedio del mes " << j+1 <<"es: "<<"\t"<<prommes<<"\n"; };

getch(); } Ejercicios Seccin 2.3.3. 2.3.3.1. Se tiene el archivo con los registros diarios de los docentes ctedra de la Universidad con la siguiente informacin: cdigo del docente nombre del docente horas diarias da ( 1, 2,,3, 4 ....30) mes (1,2,3,4 ...12)

El valor de la hora de un docente ctedra es de $15.000. Tesorera debe liquidar al final de cada mes el valor de lo que se le paga a cada docente ctedra. Utilice para el archivo un arreglo de registros y para la liquidacin una matriz. 2.3.3.2. Se tiene el archivo con los promedios ponderados de cada uno de los estudiantes y los siguientes datos: cdigo del estudiante nombre del estudiante promedio aritmtico carrera (1 = Ingeniera de sistema 2 = Ingeniera Ambiental 3 = administracin 4 = contadura pblica)

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

58

No. De semestre (1 = 2000 2 = 2001 3 = 2002 4 = 2003 5 = 2005)

Los directores de programa desean obtener de los ltimos 5 semestres : Promedio de cada carrera Promedio por semestre Si la media a nivel nacional es 3.6 cules carreras del semestre 2003 estn por debajo de la media y cules estn por encima de la media? Utilice un arreglo de registros para el archivo y matrices para acumular los promedios de los estudiantes de cada carrera en cada semestre. 2.3.3.3. Se tiene un archivo con informacin de las ventas diarias del segundo bimestre del ao 2004 de tres sucursales de la empresa de calzado Milpies de Yopal. El archivo cuenta con los siguientes datos: Cdigo de la sucursal Nombre de la sucursal Fecha (dia/mes/ao) Total venta diaria

El gerente desea tener el promedio de ventas de cada una de las sucursales del ao 2004. Adems desea tener el promedio de ventas de cada uno de los meses del segundo bimestre del ao 2004. Construya un programa en C que genere los resultados solicitados por el gerente de la empresa. Utilice registros y matrices. 2.3.3.4. Se tiene el archivo plano de los empleados de Unisangil con la siguiente informacin:

cdigo empleado nombre empleado estudio ( 1 = secundaria, 2=universitario, 3 = tcnico, 4 = ninguno) cargo(1 = docente tiempo completo, 2= administrativo, 3= docente ctedra) aos de experiencia

El director de Unisangil desea obtener: Cuntos docentes tiempo completo tienen ttulo universitario y tienen experiencia mayor de 1 ao? Cuntos empleados administrativos no tienen ningn estudio pero tienen experiencia mayor de 3 aos?

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

59

El listado con los nombres de los empleados administrativos.

Construya un programa en C que genere los resultados solicitados por el director de Unisangil. Utilice registros. 2.3.3.5. En las pasadas elecciones de mayo la Registradura Nacional con sede en Bogot necesitaba recolectar todos los datos suministrados por cada una de las mesas de votacin en el resto de ciudades del pas. Todas las mesas de una ciudad deben suministrar los siguientes datos: el nmero de mesa (No_mesa), el nmero del candidato (No_cand) y el nmero de votos para ese candidato (votos), usted debe realizarles un programa que realice los siguientes procesos: Contar el total de votos para cada uno de los candidatos y guardarlo en un vector. Usted debe tener en cuenta que existen 6 candidatos y los nmeros para cada candidato son : Luis Eduardo Garzn (1) , Nohem Sann (2), Horacio Serpa (3), Harold Bedoya (4) , Alvaro Uribe (5), Ingrid Betancour (6). Vamos a suponer que le asignamos un nmero a los Votos Nulos (7) y a los Votos en Blanco (8). Determinar cul candidato tuvo el mayor puntaje y quin el menor de los puntajes. Obtener un listado con los nmeros de los candidatos y su total ordenado de menor a mayor de acuerdo al nmero de votos. * Para las pruebas considere unos 10 candidatos.

2.3.3.6.

En la droguera "La Preferida" se est realizando una verificacin de existencias de las medicinas que se encuentran en bodega. El operario de bodega debe registrar los datos de 5000 medicinas que se encuentran all. Para cada medicina se debe registrar el nombre (nombre), la unidad (unidad) que indica si es caja o frasco, la fecha de vencimiento (venc), el tipo de medicina (tipomec), las existencias (exis), y el stock mnimo (stockmin). El operario debe clasificar las medicinas de acuerdo al tipo de medicina para llevarlos a sus estantes correspondientes y para ello debe contar cuntas medicinas existen de cada tipo. El tipomec con el nmero 1 indica que son medicinas para el dolor, el nmero 2 indica que son para la alergia, el nmero 3 indica que son para la gripa y el nmero 4 indican que son antispticos. Usted debe realizar un programa que realice los siguientes procesos: Cuente las medicinas de acuerdo al tipo. Determinar cul tipo de medicina tiene mas medicinas y cul tipo de

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

60

medicina tiene menos medicinas. Obtener un listado con los tipos de medicinas y su cantidad ordenado de menor a mayor de acuerdo al nmero de medicinas. * Para las pruebas considere unas 10 medicinas.

2.3.3.7.

En la Biblioteca de Unisangil la bibliotecaria tiene la ardua tarea de clasificar todos los libros que hay en los estantes. Se tienen cinco reas de clasificacin: 1 = contadura, 2 = bsicas, 3 = administracin, 4 = sistemas y 5 = variedades. Por cada libro la bibliotecaria tiene la siguiente informacin: cdigo del libro (cod), ttulo del libro (titulo), edicin y rea. Usted debe realizar un programa que realice los siguientes procesos: Cuente los libros que pertenecen a cada rea. Determinar cul rea tiene ms libros y cul rea tiene menos libros. Obtener un listado con las reas y su cantidad ordenado de menor a mayor de acuerdo al nmero de libros. * Para las pruebas considere unos 10 libros .

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

61

3.

ESTRUCTURAS DE DATOS DINMICAS

3.1. PUNTEROS 3.2. PUNTEROS Y VECTORES 3.3. VECTORES DINMICOS 3.4. LISTAS SIMPLEMENTE ENLAZADAS 3.5. LISTAS SIMPLEMENTE ENLAZADAS CON PROCEDIMIENTOS Y FUNCIONES 3.6. LISTAS DOBLEMENTE ENLAZADAS Las estructuras de datos dinmicas son aquellas cuyos elementos estn distribuidos en la memoria del ordenador especficamente en la parte alta de la memoria o en el denominado montculo de forma no contigua y para las cuales las funciones como malloc, calloc, new y delete son esenciales para su mantenimiento.

3.1.

PUNTEROS

Contienen direcciones de memoria. Estas direcciones apuntan a una variable de cualquier tipo de dato. La figura 16 muestra un puntero: Figura 16. Puntero
Direccin de A Valor de A

Puntero de A

Variable

Las variables de tipo puntero sirven para: Pasar informacin entre una funcin y sus puntos de llamada Proporcionan una forma de devolver varios datos

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

62

3.1.1.

Declaracin de una variable de tipo puntero

Para declarar una variable de tipo puntero se coloca primero el tipo de dato y posteriormente se coloca el nombre del puntero. La sintaxis es la siguiente: Tipo_de_dato *nombre_puntero;

Por ejemplo, un puntero a una variable de tipo entero se declara as: int *pv, *a;

3.1.2.

Asignacin de memoria a un puntero

Para asignar memoria a un puntero se utiliza cualquiera de dos funciones, ya sea utilizando la funcin New o la funcin Malloc. Funcin New. La sintaxis de esta funcin es: New (tipo_dato) Por ejemplo, new (int) permite asignar memoria a una variable de tipo entero. Funcin Malloc. La sintaxis de esta funcin es: (tipo_dato *)malloc(sizeof(tipo_dato))

3.1.3.

Asignacin de un valor a un puntero

Un puntero permite que se le asigne un valor en la direccin de memoria en la cual ste apunta. Para esto se usa la sintaxis: *nombre_puntero = valor; Por ejemplo,

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

63

*pv = 3; Si lo que se desea asignar es una direccin de memoria directamente al puntero se puede utilizar el smbolo &. Por ejemplo, pv = &v; Aqu se asigna la direccin de memoria de la variable v al puntero pv. Ejemplo 18. Puntero a un entero Un programa sencillo que permite manejar una variable de tipo puntero que apunta a un tipo de datos entero es el siguiente: #include <stdio.h> #include <conio.h> #include <iostream.h> #include<stdlib.h> void main() { int *pv; pv=new (int); cout <<"digite un valor\n"; cin>>*pv; cout<<"\ndireccin de pv"<<pv; cout<<"\ncontenido de pv"<<*pv; cout<<"\n"; getch(); }

Ejemplo 19. Asignacin de memoria a un puntero Un segundo programa de punteros en donde se observa la asignacin de memoria al puntero usando la direccin de memoria de una variable es el siguiente: #include <iostream.h> #include<stdlib.h> #include <conio.h>

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

64

void main() { int v, *pv; cout <<"digite un valor\n"; cin>>v; pv=&v; cout<<"\ndireccin de pv"<<pv; cout<<"\ncontenido de pv"<<*pv; cout<<"\ndireccin de v"<<&v; cout<<"\ncontenido de v"<<v; cout<<"\n"; getch(); }

3.2.

PUNTEROS Y VECTORES

El nombre de un vector indica la localizacin o direccin de memoria de la primera celda del vector. Entonces, si se desea indicar la direccin de memoria de los elementos de un vector se puede realizar de dos formas: La primera, se hace indicando el nombre del vector junto con la posicin de la celda pero antecediendo el smbolo &. La sintaxis es: &nombre_vector[posicin_de_celda] Por ejemplo, &X[0] &X[1] &X[2] &X[3] &X[4]

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

65

La segunda, se hace indicando el nombre del vector aadiendo el operador + para las posiciones de cada una de las celdas. La sintaxis es: nombre_vector + posicin de celda Por ejemplo, X+0 X+1 X+2 X+3 X+4 Ejemplo 20. Vector con punteros El programa utiliza las dos formas de referenciar las direcciones de memoria de las celdas en un vector, usando el smbolo & y usando la notacin nombre del vector + posicin. #include <stdio.h> #include <conio.h> #include <iostream.h> void main() {int x[2], i ; x[0]=3; x[1]=4; for (i = 0; i<2; i++) { cout<<"x[i]= "<<x[i]<<"\n"; cout<<"*(x+i)= "<<*(x+i)<<"\n"; cout<<"&x[i]= "<<&x[i] <<"\n" ; cout<<"(x+i)= "<< (x+i) <<"\n"; } getch(); } Ejercicios Seccin 3.2. 3.2.1. Genere un vector de tamao 10 con nmeros reales ledos desde teclado. Calcule el promedio e indique cuantos elementos del vector son mayores que el promedio y cuantos menores o iguales.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

66

5.2.2.

Genere un vector de tamao 20 con nmeros entre -10 y 10. Deje en un vector A todos los nmeros negativos y en un vector B todos los positivos o iguales a cero Se tienen 3 arreglos A,B,C de M elementos. Se debe crear otro arreglo NUEVO de tres elementos, donde cada elemento tenga la suma de los elementos de cada arreglo.

5.2.3.

3.3.

VECTORES DINMICOS

Un vector dinmico es aquel que no tiene un tamao fijo o esttico durante la ejecucin del programa. Por el contrario, al vector dinmico se le puede cambiar el tamao durante la ejecucin del programa. Para crear un vector dinmico de n celdas se puede usar la funcin malloc as: x = (int *) malloc (n* sizeof(int)); Ejemplo 21. Vectores dinmicos El programa permite crear un vector de n celdas e imprimir el contenido de cada celda. #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <iostream.h> void main() { int *x; int i, n; cout<<"digite el tamao del vector"<<"\n"; cin>>n; x = (int *)malloc(n*sizeof(int));

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

67

for (i=0; i<n; i++) { cout<<"digite un numero\n"; cin>>*(x + i); } for (i=0; i<n;i++) { cout<<"x["<<i<<"]= "<<*(x+i)<<"\n"; } getch(); } 3.4. LISTAS SIMPLEMENTE ENLAZADAS

3.4.1.

Definicin y declaracin de los elementos de una lista simple enlazada

Una lista simplemente enlazada consta de un conjunto de nodos o elementos de la lista, en donde cada nodo tiene la direccin de memoria al siguiente nodo. La figura 17 representa grficamente una lista simple: Figura 17. Lista simplemente enlazada

NULL

Cada nodo en la lista es un apuntador a una estructura o registro, que contiene dos tipos de campos: Un tipo de campo contiene los datos o la informacin y el otro tipo de campo se usa para almacenar un puntero que contiene la direccin de memoria del siguiente nodo. La sintaxis en el lenguaje para definir la estructura de un nodo es: struct nombre_nodo { tipo_datos campo1; tipo_datos campo2;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

68

tipo_datos campo3; ... nodo *campo_puntero_siguiente; }; Por ejemplo, el registro o el tipo de datos del nodo que contiene la informacin de los estudiantes de un aula de clase se define as: struct estudiante { int cedula; char nombre[50]; char apellidos1[50]; char apellidos2[50]; char fecha_nacimiento[20]; nodo *siguiente; }; Una vez se ha definido cada nodo, se puede declarar variables de tipo nodo. La sintaxis para declarar un nodo es: Tipo_nodo *nombre_nodo1, *nombre_nodo2... *nombre_nodoN; Por ejemplo, si se tienen las direcciones de memoria del primer, ltimo y el nodo actual, se declaran as: Nodo *primer, *ultimo, *actual;

3.4.2.

Creacin y recorrido de una lista simplemente enlazada

Para generar una lista simplemente enlazada se debe crear un puntero a cada nodo y cada uno se debe enlazar con el siguiente y para mostrarla o imprimirla se debe preguntar si no est vaco el nodo para imprimir su contenido y luego visitar el siguiente nodo. Ejemplo 22. Creacin de una lista simple #include <stdio.h>

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

69

#include <conio.h> #include <stdlib.h> #include <iostream.h> void main () { struct numeros {char num[2]; numeros *sig; }; numeros *pnum, *anterior, *primer; int n,i; //se crea el primer nodo primer=(numeros*)malloc(sizeof(numeros)); cout<<"el dato del nodo No. 1 es\n"; cin>>primer->num; //se declara primer y anterior anterior=primer; cout<<"digite la cantidad de nodos\n"; cin>>n; //se crean n nodos for(i=0;i<n;i++) {pnum=(numeros*)malloc(sizeof(numeros)); cout<<"digite el numero del nodo "<< i+2 <<"\n"; cin>>pnum->num; //se enlaza el anterior con el nuevo nodo creado anterior->sig=pnum; //se redefine el nodo anterior anterior = pnum; } pnum->sig=NULL; pnum=primer; cout<<"\n"; cout<<"la lista de numeros es: \n"; cout<<"\n"; i=1;//se recorre la lista para imprimirla while(pnum!=NULL) {cout<<"el dato del nodo No."<< i <<" es: "<< pnum->num<<"\n"; pnum=pnum->sig;i++; } getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

70

3.5.

LISTAS SIMPLEMENTE ENLAZADAS CON PROCEDIMIENTOS Y FUNCIONES

Las actividades que se pueden realizar con una lista simplemente enlazada son la creacin de la lista o de sus elementos (nodos), el recorrido de la lista, la insercin de nodos en la lista, la bsqueda de elementos y el borrado de algunos de sus nodos. En las listas no existe una limitacin en la localizacin de los nodos insertados o extrados, es decir, no necesariamente los nodos se ubican en celdas contiguas de memoria. Si esto no fuese as, insertar o borrar nodos implicara reorganizar la lista y se tendra que desplazar el resto de nodos. Por esto, las listas son consideradas estructuras flexibles, donde tanto la insercin como eliminacin pueden darse en cualquier posicin de la lista.

A continuacin, se explicar mediante un ejemplo cada una de las actividades que se pueden realizar con una lista: crear la lista, borrar nodos, insertar nodos, buscar nodos y recorrer la lista.

3.5.1.

Creacin de la lista

El procedimiento de creacin llamado void crear, se invoca desde el procedimiento principal o void main. El parmetro de entrada inicialmente, de la funcin crear es el primer nodo, el cual se crea con malloc en el procedimiento principal antes de llamarse esta funcin. Una vez se llama al entrar el primer nodo, se lee desde teclado el dato del nodo. Si el dato es la palabra FIN, esto quiere decir que no se crearn ms nodos y se le asigna a sig del nodo creado el valor NULL. Si la palabra es diferente de FIN, entonces se crea o asigna memoria con malloc a otro nuevo nodo y se vuelve a llamar la funcin crear pero el parmetro de entrada ahora no es el primero, si no el nodo que se acaba de crear, es decir reg->sig. Ejemplo 23. Crear un nodo void crear(nodo *reg) { cout<<"digite un nombre\n"; cin>> reg->nom;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

71

if ( strcmp(reg -> nom, "FIN") == 0) { reg->sig = NULL;} else { reg->sig = (nodo*)malloc(sizeof(nodo)); crear(reg->sig); } return; } 3.5.2. Recorrer la lista

El procedimiento de recorrer una lista simplemente enlazada llamado void mostrar, recibe como parmetro inicial el primer nodo. Si reg->sig tiene un valor igual a NULL quiere decir que ya se termina la lista, por lo que se debe retornar nuevamente al programa principal, de lo contrario, si reg->sig tiene un valor diferente de NULL es porque existe un nodo siguiente, entonces, se debe imprimir el dato que contiene el nodo y se debe volver a llamar el procedimiento de mostrar pero recibiendo como parmetro de entrada el nodo siguiente, es decir reg->sig. Ejemplo 24.Mostrar la lista simplemente enlazada void mostrar(nodo *reg) { if (reg->sig !=NULL) { cout<<reg->nom<<"\n"; mostrar(reg->sig); } return; } 3.5.3. Insercin de un nodo

La funcin de insertar un nodo llamada insertar, comienza inicialmente, solicitando de teclado el valor del nuevo dato a ingresar en la lista (nuevodato), y el valor del nodo que se encuentra delante del que se va a insertar (objetivo). Al igual que los anteriores procedimientos, la funcin insertar recibe como parmetro de entrada el primer nodo. Si al comparar (con la funcin de cadenas comparar strcmp) el dato que contiene el primer nodo con el objetivo, estos son iguales, significa que el nuevo dato a insertar

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

72

debe ocupar la primera posicin. Por ello, se crea un nuevo nodo (nuevoreg) con malloc, se copia el contenido del nuevo dato en el nuevo nodo(con la funcin de cadenas copiar strcpy); el siguiente del nuevoreg se apunta al primer nodo y por ltimo se renombra la lista, asignando el nuevo nodo creado como primer nodo como se observa en la figura 18. Figura 18. Insercin de un nodo al comienzo de una lista simple
primer

nuevoreg

Si al comparar el dato del registro actual con el objetivo, y estos no son iguales, entonces, se debe buscar el objetivo en la lista. Para esto se utiliza la funcin localizar, la cual retorna el valor del nodo anterior al nodo que coincide con el objetivo. Si no encuentra el objetivo en la lista el valor de anterior es NULL, imprimiendo un mensaje que indica que el objetivo no se encuentra en la lista. De lo contrario, se puede insertar el nodo en medio del nodo anterior y del nodo siguiente al anterior. Figura 19. Insercin de un nodo en medio de dos nodos en una lista simple
anterior Anterior->sig

D
nuevoreg

Para insertar en medio de los dos nodos como se observa en la figura 19, se debe primero crear el nodo con malloc, luego se copia el nuevodato en el nuevo registro o nodo y se realizan los enlaces. El primer enlace se hace asignando a nuevoreg->sig la direccin de memoria que contiene anterior->sig y el segundo enlace se hace asignando a anterior->sig la direccin de memoria del nuevo registro o nuevoreg. Finalmente, la funcin de insertar devuelve al programa principal el primer nodo de la nueva lista enlazada.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

73

Ejemplo 25. Insercin de un nodo en una lista simplemente enlazada

nodo* insertar(nodo *reg) { nodo *nuevoreg; nodo *anterior; char nuevodato[50]; char objetivo[50]; nodo *localizar(nodo*, char [50]); cout<<"Nuevo dato:\n"; cin>>nuevodato; cout<<"nodo que va adelante:\n"; cin>>objetivo; if (strcmp(reg->nom, objetivo)==0) { nuevoreg = (nodo *)malloc(sizeof(nodo)); strcpy(nuevoreg->nom, nuevodato); nuevoreg -> sig = primer; primer = nuevoreg; } else { anterior = localizar(reg,objetivo); if (anterior == NULL ) cout<<"no hay coincidencia\n"; else {nuevoreg = (nodo *)malloc (sizeof(nodo)); strcpy(nuevoreg->nom,nuevodato); nuevoreg->sig = anterior->sig; anterior->sig = nuevoreg; } } return(primer); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

74

3.5.4.

Borrar un nodo

La funcin borrar, permite eliminar un nodo de la lista. Al igual que la funcin de insertar, recibe como parmetro inicial el primer nodo de la vieja lista y devuelve al programa principal el primer nodo de la nueva lista. Para borrar un nodo, se debe localizar el nodo objetivo. Como se observa en la figura 20, si el objetivo es el primer nodo, se crea un temporal que guarda la direccin de memoria del segundo nodo, una vez hecho esto, se puede eliminar el primer nodo, y posteriormente, se asigna el segundo nodo, es decir primer->sig o temporal como primer nodo. Figura 20. Eliminacin del primer nodo de una lista simple
temp

A
primer

Si el objetivo no se encuentra, se imprime un mensaje que indica que no se encuentra el nodo. Ahora bien, si no se desea borrar el primer nodo, sino un nodo intermedio como se observa en la figura 21, se crea igualmente un temporal que contiene la direccin de memoria del siguiente nodo al que se desea borrar , es decir anterior->sig->sig, una vez hecho esto, se borra el nodo y posteriormente se enlaza la lista, asignndole a anterior->sig la direccin de memoria del nodo temporal. Figura 21. Eliminacin de un nodo intermedio en una lista simple
primer anterior temp

Ejemplo 26. Borrar un nodo de una lista simplemente enlazada nodo *borrar(nodo *primer) { nodo *localizar(nodo *, char[50]); nodo *temp; nodo *anterior;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

75

char objetivo[50]; cout<<"dato a borrar:\n"; cin>>objetivo; if (strcmp(primer->nom, objetivo) == 0) {temp = primer->sig; free(primer); primer=temp; } else {anterior = localizar(primer,objetivo); if (anterior == NULL) cout<<"No se encuentra coincidencia\n"; else { temp=anterior->sig->sig; free(anterior->sig); anterior->sig =temp; } } return(primer); } El programa completo como sigue: Ejemplo 27. Programa de una lista simplemente enlazada con procedimientos #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <iostream.h> struct nodo { char nom[50]; nodo *sig; }; nodo *pnodo, *primer; int opcion; void crear(nodo *reg)

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

76

cout<<"digite un nombre\n"; cin>> reg->nom; if ( strcmp(reg -> nom, "FIN") == 0) { reg->sig = NULL;} else { reg->sig = (nodo*)malloc(sizeof(nodo)); crear(reg->sig); } return;

} void mostrar(nodo *reg) { if (reg->sig !=NULL) { cout<<reg->nom<<"\n"; mostrar(reg->sig); } return; } nodo* insertar(nodo *reg) { nodo *nuevoreg; nodo *anterior; char nuevodato[50]; char objetivo[50]; nodo *localizar(nodo*, char [50]); cout<<"Nuevo dato:\n"; cin>>nuevodato; cout<<"nodo que va adelante:\n"; cin>>objetivo; if (strcmp(reg->nom, objetivo)==0) { nuevoreg = (nodo *)malloc(sizeof(nodo));

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

77

strcpy(nuevoreg->nom, nuevodato); nuevoreg -> sig = primer; primer = nuevoreg; } else { anterior = localizar(reg,objetivo); if (anterior == NULL ) cout<<"no hay coincidencia\n"; else {nuevoreg = (nodo *)malloc (sizeof(nodo)); strcpy(nuevoreg->nom,nuevodato); nuevoreg->sig = anterior->sig; anterior->sig = nuevoreg; } } return(primer); } nodo *borrar(nodo *primer) { nodo *localizar(nodo *, char[50]); nodo *temp; nodo *anterior; char objetivo[50]; cout<<"dato a borrar:\n"; cin>>objetivo; if (strcmp(primer->nom, objetivo) == 0) {temp = primer->sig; free(primer); primer=temp; } else {anterior = localizar(primer,objetivo); if (anterior == NULL) cout<<"No se encuentra coincidencia\n"; else { temp=anterior->sig->sig; free(anterior->sig); anterior->sig =temp; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

78

} return(primer); } nodo* localizar(nodo *reg, char objetivo[50]) { if (strcmp(reg->sig->nom, objetivo) == 0) return(reg); else { if (reg->sig->sig == NULL) return (NULL); else localizar (reg->sig, objetivo); } } void main() { do { cout<<"\ndigite 1=crear 2=insertar 3=borrar 4= salir\n"; cin>>opcion; switch (opcion) { case 1 : primer = (nodo*)malloc(sizeof(nodo)); crear(primer); cout<<"la lista es:\n"; mostrar(primer); continue; case 2 : primer = insertar(primer); cout<<"la lista es:\n"; mostrar(primer); continue; case 3: primer = borrar(primer); cout<<"la lista es:\n"; mostrar(primer);

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

79

continue; case 4 : break; } } while(opcion != 4); getch(); } Ejercicios Seccin 3.5. 3.5.1. Realice un programa que imprima la direccin de memoria de todas las celdas de una cadena de caracteres. 3.5.2. Se tiene un vector con nmeros enteros. Imprima la direccin de memoria donde se encuentre un nmero entero K dado. 3.5.3. Carolina recoge el da lunes, martes, jueves, viernes, sbado y domingo los valores de temperatura diaria de la ciudad, durante 2 semanas. Realice una lista simplemente enlazada para recoger los datos. Sin embargo, Carolina recuerda que faltaba la temperatura del da mircoles de ambas semanas. Inserte el valor de temperatura del da mircoles en la lista simple enlazada. 3.5.4. Genere un vector de tamao 10 con nmeros reales ledos desde teclado. Calcule el promedio e indique cuantos elementos del vector son mayores que el promedio y cuantos menores o iguales. Utilice la notacin de punteros (x+i). 3.5.5. Genere un vector de tamao 20 con nmeros entre 0 y 10. Deje en un vector A todos los nmeros negativos y en un vector B todos los positivos o iguales a cero. Utilice la notacin de punteros (x+i). 3.5.6. Se tienen 3 arreglos A,B,C de M elementos. Se debe crear otro arreglo NUEVO de tres elementos, donde cada elemento tenga la suma de los elementos de cada arreglo. Utilice la notacin de punteros (x+i). 3.5.7. Realice un programa donde se utilicen punteros como parmetros de una funcin que devuelva el triple del valor inicial. 3.5.8. Utilice una lista simplemente enlazada para guardar la informacin de los

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

80

empleados de una empresa X. Los datos son: cdula del empleado nombre del empleado sueldo actual Imprima el valor del nuevo sueldo si este se incrementa en un 10% si el sueldo actual es menos del mnimo y del 5% si es mayor del mnimo. Imprima la lista completa con la cdula del empleado y el sueldo actual. Imprima adems la direccin de memoria del primer y ltimo de los empleados. 3.5.9. Realice un programa donde se utilicen punteros como parmetros de una funcin que devuelva la tangente del valor inicial. 3.5.10. Se tiene un vector llamado alfa con las letras del alfabeto en desorden. Ordenar el vector, e imprimir el vector ordenado. Utilice vectores dinmicos. 3.5.11. Se tiene un listado de precios de los N productos de un almacn en un vector C. Llenar un vector D con el valor del iva (16%) de cada uno de los productos. Imprimir el vector D ordenado. Utilice vectores dinmicos. 3.5.12. Se tiene almacenado en un vector el valor de los vuelos nacionales de una aerolnea. Ordenar el vector e imprimirlo. Adems contar cuntos vuelos nacionales superan los 800.000 y cuntos estn entre 200.000 y 300.000. Utilice vectores dinmicos. 3.5.13. Generar un vector dinmico con la serie de Fibonacci. La serie de Fibonacci es infinita. Halle trminos de la serie hasta que el nuevo nmero generado sea mayor que un nmero dado N. La serie de Fibonacci es 0,1,1,2,3,5,8,13,21,.. empieza en 0 y 1. 3.5.14. La empresa de busetas de la ciudad desea liquidar en forma automtica el pago de los servicios a sus chferes, para lo cual se suministra la siguiente informacin: Realice una lista simple con la informacin de los choferes: cedula nombre tipo chofer 1 = normal 2 = experto estado 1 = activo 2 = inactivo

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

81

valor a pagar (inicialmente vaco) tipo de servicio 1 = ruta 1 2 = ruta 2

Encuentre el valor a pagar para los choferes activos. A cada chofer se le pagar el salario mnimo ms un incremento sobre el salario mnimo teniendo en cuenta la siguiente tabla: % valor del incremento sobre el salario mnimo 1 2 5 10 10 15

Tipo de chofer 1 2

3.5.15. Calcular la varianza de un vector dinmico de N observaciones (nmeros). 3.5.16. La hacienda La Primavera cuenta con 2000 cabezas de ganado, y el administrador de la finca controla cada animal con un chip que enva informacin a un sistema centralizado, ste lee la siguiente informacin: No. de animal Raza (1= holstein 2= pardo suizo 3= vacuno) Genero (1 = hembra 2= macho) Peso Edad

El dueo de la finca desea consultar: a. b. c. d. cuntas vacas son de raza pardo suizo cuntos toros holstein son menores de 5 aos cunto ganado pesa ms de 100 kilogramos? Imprimir el nmero de los animales mayor de 3 aos

3.5.17. El supermercado Corabastos vende una gran variedad de productos y el administrador del negocio desea un sistema que lea la siguiente informacin: Cdigo del producto Tipo de producto (1 =aseo 2= comestible 3= fruta y verdura) Marca Ao de compra Precio

El dueo de Corabastos desea consultar:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

82

a. Cuntos productos son comestibles y adquiridos el ao pasado b. Cuntos productos de aseo fueron comprados en VaniPlast c. Una poltica del gobierno aplica el IVA a todos los productos de aseo. Entonces se debe obtener el listado de los productos (solo el cdigo) con el valor del iva. d. Cuntas productos de tipo frutas y verduras valen menos de $2000?

3.6.

LISTAS DOBLEMENTE ENLAZADAS

Una lista doblemente enlazada est formada por nodos que contienen dos direcciones de memoria, una que apunta al nodo de la derecha y otra que apunta al nodo de la izquierda, como se observa en la figura 22. Adems el primer y ltimo nodo tendr direccin de memoria vaca a izquierda y derecha respectivamente. Figura 22. Lista doblemente enlazada
INFORMACION INFORMACION

NULL

INFORMACION

NULL

3.6.1. Creacin de la lista doble

En este procedimiento inicialmente se crea el primer nodo, se almacena la informacin, se asigna NULL a la derecha e izquierda del nodo y por ltimo, se asigna la direccin de memoria del primer nodo al nodo anterior como se observa en la figura 23. Figura 23. Creacin de nodo en una lista doblemente enlazada

NULL

INFORMACION

NULL

El cdigo que realiza esto es el siguiente:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

83

Ejemplo 28. Crear un nodo en una lista doblemente enlazada //crea el primer nodo, llena la informacin y asigna vaco a la derecha e izquierda primer=new nodo; cout<<"DIGITE EL PRIMER NODO DE LA LISTA: "<<endl; cin>>primer->info; primer->der=NULL; primer->izq=NULL; // anterior es igual al primer nodo anterior=primer; Si se desean agregar ms nodos, entonces se solicita la cantidad de nodos y se ejecuta un procedimiento repetitivo mientras que el contador de nodos no sea mayor a la cantidad solicitada. En el procedimiento repetitivo, se crea el nodo actual, se almacena informacin y se asigna NULL a la derecha de actual. A la izquierda de actual se le asigna la direccin del nodo anterior, a la derecha del nodo anterior se le asigna el nodo actual y por ltimo se asigna la direccin de memoria del nodo actual al nodo anterior como se observa en la figura 24: Figura 24. Creacin de varios nodos en una lista doble
INFORMACION

NULL

INFORMACION actual

NULL

anterior

Ahora actual es anterior

Ejemplo 29. Crear varios nodos en una lista doble while(x=='s') { cout<<"DIGITE LA CANTIDAD DE NODOS A AGREGAR "<<endl; cin>>n; do { //crea el nodo actual y llena la informacin actual=new nodo; cout<<"DIGITE UN NUMERO"<<endl; cin>>actual->info; actual->der=NULL;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

84

//se enlaza el nodo actual con el anterior actual->izq=anterior; //se enlaza el nodo anterior con el actual anterior->der=actual; //ahora el actual es el anterior anterior=actual; j++; } while(j!=n); cout<<"DESEA AGREGAR MAS NUMEROS? <si=s o no=n> "<<endl; cin>>x; j=0; recorreder(primer); recorreizq(anterior); } return primer; }

3.6.2. Recorrer la lista doblemente enlazada hacia la derecha

El procedimiento del recorrido de una lista doblemente enlazada hacia la derecha recibe como parmetro de entrada el primer nodo de la lista. En este procedimiento se encuentra un proceso repetitivo (hacer mientras) que se ejecuta mientras el nodo es diferente de vaco. Si esto es cierto, entonces, se imprime la informacin del nodo y se asigna al nodo actual la direccin de memoria del nodo de la derecha. El cdigo del procedimiento es el siguiente: Ejemplo 30. Recorrido hacia la derecha en una lista doblemente enlazada void recorreder(nodo *primer) { nodo *actual; actual=primer; cout<<endl<<endl<<endl; cout<<"LA LISTA DOBLEMENTE ENLAZADA HACIA LA DERECHA:"<<endl; //recorre mientras que el nodo no sea vaco while(actual!=NULL) {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

85

//muestra la informacin del nodo cout<< actual->info<<"=>"; //pasa al nodo de la derecha actual=actual->der; } cout<< "NULL"<<endl; getch(); }

3.6.3. Recorrer la lista doblemente enlazada hacia la izquierda

El procedimiento del recorrido de una lista doblemente enlazada hacia la izquierda recibe como parmetro de entrada el primer nodo de la lista. En este procedimiento se encuentra un proceso repetitivo (hacer mientras) que se ejecuta mientras que el nodo es diferente de vaco. Si esto es cierto, entonces, se imprime la informacin del nodo y se asigna al nodo actual la direccin de memoria del nodo de la izquierda. El cdigo del procedimiento es el siguiente: Ejemplo 31. Recorrido hacia la izquierda en una lista doblemente enlazada //recorre la lista hacia la izquierda void recorreizq(nodo *primer) { nodo *actual; actual=primer; cout<<"LA LISTA DOBLEMENTE ENLAZADA HACIA LA IZQUIERDA:"<<endl; //recorre mientras que el nodo no sea vaco while(actual!=NULL) { //muestra la informacin del nodo cout<< actual->info<<"=>"; //pasa al nodo de la izquierda actual=actual->izq; } cout<< "NULL"<<endl<<endl<<endl; getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

86

3.6.4. Insertar un nodo al comienzo de la lista Para insertar un nodo al comienzo de la lista se crea un nuevo nodo y se almacena su valor. Posteriormente, se enlaza el nuevo nodo por el lado derecho con el primero de la lista antigua, el izquierdo del primer nodo con el nuevo nodo y se renombra el primer nodo con el nodo que se acaba de crear. Se recorre la lista hacia la derecha entrando el primer nodo de la nueva lista y para recorrer la lista hacia la izquierda se busca el ltimo nodo de la nueva lista. La lista obtenida se observa en la figura 25. Figura 25. Insertar un nodo al comienzo de la lista doble
INFORMACION INFORMACION

NULL

Primer INFORMACION

Nuevo nodo

Ejemplo 32. Insercin de un nodo al comienzo de una lista doblemente enlazada

nodo *insertainicio(nodo *primer) { nodo *actual,*ultimo; actual=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR"<<endl; cin>>actual->info; actual->der=primer; primer->izq=actual; primer=actual; actual->izq=NULL; //se va al ultimo ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo);

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

87

return primer; }

3.6.5. Insertar un nodo antes de un valor dado

Para insertar un nodo antes de un valor que se encuentra en la lista se solicita antes de qu nodo se desea insertar el nuevo dato como se observa en la figura 26. Figura 26. Insercin de un nodo antes de un valor dado en una lista doble
INFORMACION INFORMACION

INFORMACION

INFORMACION NULL

NULL

Primer

INFORMACION

Nuevo nodo

Se utiliza un while para buscar dicho dato, preguntando si el nodo actual es diferente del dato que se est buscando y si la bandera es verdadera.

while(actual->info!=dato && b=='v')

Mientras esta condicin sea cierta se pregunta si el nodo de la derecha de actual es diferente de vaco y si esto se cumple se desplaza hacia el nodo de la derecha.

if(actual->der!=NULL) { anterior=actual; actual=actual->der; }


Sin embargo, si el nodo de la derecha es vaco quiere decir que ya se termin de revisar la lista y nunca un nodo coincidi con el valor que se est buscando, entonces, se coloca la bandera en falso y se imprime en pantalla un mensaje de error.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

88

else { b='f'; cout<<endl<<endl<<endl; cout<<"ERROR "<<endl; cout<<"EL NUMERO NO EXISTE EN LA LISTA"<<endl; cout<<"LA LISTA SIGUE QUEDANDO IGUAL "<<endl<<endl; }
Despus del while, si la bandera es verdadera, es decir, se encontr el nodo que se buscaba, se crea un nuevo nodo, se solicita el valor que contendr el nodo y se coloca vaco a su derecha e izquierda.

If (b=='v') { nuevonodo=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR ANTES DE "<<dato<<" : "; cin>>dato; nuevonodo->info=dato; nuevonodo->der=NULL; nuevonodo->izq=NULL;
Si el dato que se buscaba es el primero entonces la derecha del nuevo nodo se enlaza con el actual, la izquierda del actual se enlaza con el nuevo nodo, se coloca vaco a la izquierda del nuevo nodo y se renombra el nuevo nodo como el primero de la lista.

if(primer==actual) { nuevonodo->der=actual; actual->izq=nuevonodo; nuevonodo->izq=NULL; primer=nuevonodo; }


Por ltimo, si se debe insertar en medio de dos nodos se coloca a la derecha del nodo anterior el nuevo nodo, a la izquierda del nuevo nodo el anterior, a la derecha del nuevo nodo el actual y a la izquierda del actual el nuevonodo.

else //si se debe insertar en medio de dos nodos {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

89

anterior->der=nuevonodo; nuevonodo->izq=anterior; nuevonodo->der=actual; actual->izq=nuevonodo;

Ejemplo 33. Insercin de un nodo antes de un valor dado en una lista doblemente enlazada //para insertar un nodo antes de algun dato de la lista: nodo *inserta_antes(nodo *primer) { nodo *actual,*anterior,*nuevonodo,*ultimo; char b='v'; double dato; cout<<"DETRAS DE QUE NUMERO DESEA INSERTAR NUMERO?: "; cin>>dato; actual=primer; //se busca el nodo en la lista while(actual->info!=dato && b=='v') { if(actual->der!=NULL) { anterior=actual; actual=actual->der; } else { b='f'; cout<<endl<<endl<<endl; cout<<"ERROR "<<endl; cout<<"EL NUMERO NO EXISTE EN LA LISTA"<<endl; cout<<"LA LISTA SIGUE QUEDANDO IGUAL "<<endl<<endl; } } //si encontro el nuevo nodo se enlaza con el resto de la lista if(b=='v') { nuevonodo=new nodo;

EL

NUEVO

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

90

cout<<"DIGITE EL NUMERO A INSERTAR ANTES DE "<<dato<<" : "; cin>>dato; nuevonodo->info=dato; nuevonodo->der=NULL; nuevonodo->izq=NULL; // si debe ser el primer nodo if(primer==actual) { nuevonodo->der=actual; actual->izq=nuevonodo; nuevonodo->izq=NULL; primer=nuevonodo; } else //si se debe insertar en medio de dos nodos { anterior->der=nuevonodo; nuevonodo->izq=anterior; nuevonodo->der=actual; actual->izq=nuevonodo; } } ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo); return primer; }

3.6.6. Insertar un nodo al final de la lista Para insertar un nodo al final de la lista se utiliza un while para recorrer la lista hasta ir al ltimo nodo. Al salir del while, se crea un nuevo nodo, se digita un valor para dicho nodo, se coloca a la izquierda del nuevo nodo el actual, es decir, el ltimo nodo, a la derecha del actual se coloca el nuevo nodo y a la derecha del nuevo nodo se le asigna vaco como se observa en la figura 27.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

91

Figura 27. Insercin de un nodo al final de una lista doble


INFORMACION INFORMACION

Primer INFORMACION

Nuevo nodo

Ejemplo 34. Insercin de un nodo al final de una lista doblemente enlazada //para insertar un nodo y dejarlo como el ultimo de la lista: nodo *insertafinal(nodo *primer) { nodo *actual,*nuevonodo; actual=primer; while(actual->der!=NULL) { actual=actual->der; } nuevonodo=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR: "; cin>>nuevonodo->info; nuevonodo->izq=actual; actual->der=nuevonodo; nuevonodo->der=NULL; recorreder(primer); recorreizq(nuevonodo); return primer; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

92

3.6.7. Borrar al comienzo de la lista Para eliminar el nodo que se encuentra al comienzo de la lista como se observa en la figura 28, inicialmente se verifica si la lista tiene ms de un nodo. Si la lista tiene varios nodos, se asigna como primero de la lista el segundo nodo, es decir, primer debe ser igual al derecho de actual(primero en la lista). Adems, se asigna vaco a la izquierda del primer nodo y posteriormente se borra el actual. Si la lista solamente tiene un nodo, se asigna el primer nodo como vaco y se borra el nodo existente o el nodo actual. Figura 28. Borrar un nodo al comienzo de la lista doble
INFORMACION INFORMACION INFORMACION

Primer
Ejemplo 35. Borrar un nodo al comienzo de una lista doblemente enlazada //eliminar el primero de la lista nodo *eliminaprimero(nodo *primer) { nodo *actual,*ultimo; actual=primer; //si el derecho del primero es diferente de vaco este nodo se renombra como el primero if(actual->der!=NULL) { primer=actual->der; primer->izq=NULL; } else //si en la lista solo hay un nodo { primer=NULL; delete actual; recorreder(primer); recorreizq(primer); return primer; } //se borra el actual delete actual;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

93

ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo); return primer; }

3.6.8. Borrar el ltimo nodo de la lista

Para borrar el ltimo nodo de la lista se verifica si solamente existe un nodo en la lista como se observa en la figura 29. Si esto se cumple, se asigna vaco a primer y se borra el primer y nico nodo de la lista. Si existe ms de un nodo en la lista se utiliza un while para recorrer la lista hasta llegar al ltimo nodo. Una vez, se ha encontrado el ltimo nodo se asigna vaco a la derecha del ltimo nodo y se borra el nodo actual. Figura 29. Borrar el ltimo nodo de una lista doblemente enlazada

INFORMACION

INFORMACION

INFORMACION

ultimo

Ejemplo 36. Borrar el ltimo nodo de una lista doblemente enlazada nodo *elimina_ultimo(nodo *primer) { nodo *actual,*ultimo; //si existe solo un nodo if(primer->der==NULL) { primer=NULL;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

94

ultimo=NULL; delete primer; } //si existe en la lista ms de un nodo else { actual=primer; //se recorre la lista hasta llegar al final while(actual->der!=NULL) { ultimo=actual; actual=actual->der; } ultimo->der=NULL; delete actual; } recorreder(primer); recorreizq(ultimo); return primer; } 3.6.9. Borrar un nodo cualquiera de la lista Para borrar un nodo X de la lista se deben tener en cuenta diversos casos. Sin embargo, el procedimiento generalizado del borrado de un nodo de la lista es el que se puede observar en la figura 30:

Figura 30. Borrar un nodo cualquiera


INFORMACION INFORMACION

INFORMACION

anterior

pu

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

95

- Si en la lista solamente existe un nodo, se hace primer y ltimo igual a vaco y se borra el primer.

if(primer->der==NULL) { primer=NULL; ultimo=NULL; delete primer; }


Si en la lista existe mas de un nodo, se recorre la lista hasta llegar al final

else { actual=primer; //se recorre la lista hasta llegar al final while(actual->der!=NULL) { ultimo=actual; actual=actual->der; } ultimo->der=NULL; delete actual; }
Si se desea eliminar cualquier dato se debe buscar el dato, el cdigo que permite realizar dicha bsqueda retornando la direccin de memoria del nodo anterior es el siguiente:

while(actual->info!=dato && b=='v') { if(actual->der!=NULL) anterior=actual; actual=actual->der; pu=actual;


Si la bsqueda es satisfactoria pero el nodo a borrar es el nico de la lista se hace primer igual a NULL y se borra el nodo.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

96

if(actual->der==NULL&&actual->izq==NULL) { primer=NULL; delete primer; recorreder(primer); recorreizq(primer); return primer; }


Si el nodo a borrar es el ltimo se hace la derecha del nodo anterior igual a NULL y se borra el nodo actual

{ anterior->der=NULL; delete actual; recorreder(primer); recorreizq(anterior); return primer; }


Si no se encontr ningn nodo aparece una mensaje de error y de nuevo se retorna el primero de la lista

if(b=='f') { cout<<endl<<endl<<endl; cout<<"ERROR "<<endl; cout<<"EL NUMERO NO EXISTE EN LA LISTA "<<endl; cout<<"LA LISTA SIGUE QUEDANDO IGUAL "<<endl; cout<<endl<<endl; recorreder(primer); recorreizq(actual); return primer; }
De lo contrario, si la bsqueda es satisfactoria se debe preguntar si es el primero de los nodos. Si el nodo a borrar es el primero se renombra como primer nodo al nodo de la derecha, se hace el izquierdo del primero igual a vaco o NULL y se recorre la lista hasta ubicar el ltimo.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

97

if(primer==actual) { primer=actual->der; primer->izq=NULL; ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; }


Si no es el primero de la lista pero el nodo a borrar se encuentra entre dos nodos se enlaza la derecha del nodo anterior con el nodo pu o el siguiente nodo al que se va a borrar y enlazar el izquierdo del nodo siguiente al que se va a borrar con el nodo anterior.

else { anterior->der=pu; pu->izq=anterior; ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; }


El cdigo del programa completo es el siguiente: Ejemplo 37. Programa completo lista doblemente enlazada #include <conio.h> #include <iostream.h> #include <stdio.h> struct nodo { double info; nodo *der; nodo *izq; };

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

98

nodo *creadesdefin(nodo *p); nodo *creanormal(nodo *p); nodo *insertainicio(nodo *p); nodo *inserta_antes(nodo *primer); nodo *inserta_final(nodo *primer); nodo *elimina_primero(nodo *primer); nodo *elimina_ultimo(nodo *primer); nodo *elimina_cualquier(nodo *primer); void recorreder(nodo *p); void recorreizq(nodo *p);

void main() { int opc=0; nodo *puntero=NULL; while(opc!=8) { cout<<"------------MENU PRINCIPAL DE LISTAS DOBLEMENTE ENLAZADAS------------"<<endl<<endl; cout<<"1: CREAR LOS NODOS EN SU ORDEN"<<endl; cout<<"2: INSERTAR UN NODO AL COMIENZO DE LA LISTA"<<endl; cout<<"3: INSERTAR UN NODO ANTES DE UN VALOR DADO"<<endl; cout<<"4: INSERTAR UN NODO AL FINAL DE LA LISTA"<<endl; cout<<"5: BORRAR EL PRIMER NODO DE LA LISTA"<<endl; cout<<"6: BORRAR EL ULTIMO NODO DE LA LISTA"<<endl; cout<<"7: BORRAR CUALQUIER NODO DE LA LISTA"<<endl; cout<<"8: SALIR DEL PROGRAMA"<<endl<<endl; cout<<"SELECCIONE UNA OPCION (digite un numero de 1 - 8):"<<endl; cin>>opc; cout<<endl<<endl; switch(opc) { case 1: cout<<"\tCREAR LOS NODOS EN SU ORDEN"<<endl; puntero=creanormal(puntero); break; case 2: cout<<"\tINSERTAR UN NODO AL COMIENZO DE LA

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

99

LISTA"<<endl; puntero=insertainicio(puntero); break; case 3: cout<<"\tINSERTAR UN NODO ANTES DE UN VALOR DADO"<<endl; puntero=inserta_antes(puntero); break; case 4: cout<<"\tINSERTA UN NODO AL FINAL DE LA LISTA"<<endl; puntero=inserta_final(puntero); break; case 5: cout<<"\tBORRA EL PRIMER NODO DE LA LISTA"<<endl; puntero=elimina_primero(puntero); break; case 6: cout<<"\tBORRA EL LTIMO NODO DE LA LISTA"<<endl; puntero=elimina_ultimo(puntero); break; case 7: cout<<"\tBORRA CUALQUIER NODO DE LA LISTA"<<endl; puntero=elimina_cualquier(puntero); break; case 8: cout<<"\tSALIR DEL PROGRAMA"<<endl; cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl; cout<<"ESTRUCTURA DE DATOS"<<endl; break; } } } //crea los nodos en su orden nodo *creanormal(nodo *primer) { int n,j=0; char x; nodo *actual,*anterior; //crea el primer nodo, llena la informacin y asigna vaco a la derecha e izquierda primer=new nodo;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

100

cout<<"DIGITE EL PRIMER NODO DE LA LISTA: "<<endl; cin>>primer->info; primer->der=NULL; primer->izq=NULL; // anterior es igual al primer nodo anterior=primer; cout<<"DESEA AGREGAR MAS NUMEROS <si=s / no=n> "<<endl; cin>>x; while(x=='s') { cout<<"DIGITE LA CANTIDAD DE NODOS A AGREGAR "<<endl; cin>>n; do { //crea el nodo actual y llena la informacin actual=new nodo; cout<<"DIGITE UN NUMERO"<<endl; cin>>actual->info; actual->der=NULL; //se enlaza el nodo actual con el anterior actual->izq=anterior; //se enlaza el nodo anterior con el actual anterior->der=actual; //ahora el actual es el anterior anterior=actual; j++; } while(j!=n); cout<<"DESEA AGREGAR MAS NUMEROS? <si=s o no=n> "<<endl; cin>>x; j=0; recorreder(primer); recorreizq(anterior); } return primer; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

101

// recorre la lista hacia la derecha void recorreder(nodo *primer) { nodo *actual; actual=primer; cout<<endl<<endl<<endl; cout<<"LA LISTA DOBLEMENTE ENLAZADA HACIA LA DERECHA:"<<endl; //recorre mientras que el nodo no sea vaco while(actual!=NULL) { //muestra la informacin del nodo cout<< actual->info<<"=>"; //pasa al nodo de la derecha actual=actual->der; } cout<< "NULL"<<endl; getch(); } //recorre la nodo hacia la izquierda void recorreizq(nodo *primer) { nodo *actual; actual=primer; cout<<"LA LISTA DOBLEMENTE ENLAZADA HACIA LA IZQUIERDA:"<<endl; //recorre mientras que el nodo no sea vaco while(actual!=NULL) { //muestra la informacin del nodo cout<< actual->info<<"=>"; //pasa al nodo de la izquierda actual=actual->izq; } cout<< "NULL"<<endl<<endl<<endl; getch(); } nodo *insertainicio(nodo *primer) {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

102

nodo *actual,*ultimo; actual=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR"<<endl; cin>>actual->info; actual->der=primer; primer->izq=actual; primer=actual; actual->izq=NULL; //se va al ultimo ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo); return primer; } //para insertar un nodo antes de algun dato de la lista: nodo *inserta_antes(nodo *primer) { nodo *actual,*anterior,*nuevonodo,*ultimo; char b='v'; double dato; cout<<"DETRAS DE QUE NUMERO DESEA INSERTAR NUMERO?: "; cin>>dato; actual=primer; //se busca el nodo en la lista while(actual->info!=dato && b=='v') { if(actual->der!=NULL) { anterior=actual; actual=actual->der; } else { b='f';

EL

NUEVO

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

103

cout<<endl<<endl<<endl; cout<<"ERROR "<<endl; cout<<"EL NUMERO NO EXISTE EN LA LISTA"<<endl; cout<<"LA LISTA SIGUE QUEDANDO IGUAL "<<endl<<endl; } } //si encontro el nuevo nodo se enlaza con el resto de la lista if(b=='v') { nuevonodo=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR ANTES DE "<<dato<<" : "; cin>>dato; nuevonodo->info=dato; nuevonodo->der=NULL; nuevonodo->izq=NULL; // si debe ser el primer nodo if(primer==actual) { nuevonodo->der=actual; actual->izq=nuevonodo; nuevonodo->izq=NULL; primer=nuevonodo; } else //si se debe insertar en medio de dos nodos { anterior->der=nuevonodo; nuevonodo->izq=anterior; nuevonodo->der=actual; actual->izq=nuevonodo; } } ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo); return primer; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

104

//para insertar un nodo y dejarlo como el ultimo de la lista: nodo *inserta_final(nodo *primer) { nodo *actual,*nuevonodo; actual=primer; while(actual->der!=NULL) { actual=actual->der; } nuevonodo=new nodo; cout<<"DIGITE EL NUMERO A INSERTAR: "; cin>>nuevonodo->info; nuevonodo->izq=actual; actual->der=nuevonodo; nuevonodo->der=NULL; recorreder(primer); recorreizq(nuevonodo); return primer; } //eliminar el primero de la lista nodo *elimina_primero(nodo *primer) { nodo *actual,*ultimo; actual=primer; //si el derecho del primero es diferente de vaco este nodo se renombra como el primero if(actual->der!=NULL) { primer=actual->der; primer->izq=NULL; } else //si en la lista solo hay un nodo { primer=NULL; delete actual; recorreder(primer);

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

105

recorreizq(primer); return primer; } //se borra el actual delete actual; ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } recorreder(primer); recorreizq(ultimo); return primer; } //para eliminar el ultimo nodo de la lista; nodo *elimina_ultimo(nodo *primer) { nodo *actual,*ultimo; //si existe solo un nodo if(primer->der==NULL) { primer=NULL; ultimo=NULL; delete primer; } //si existe en la lista ms de un nodo else { actual=primer; //se recorre la lista hasta llegar al final while(actual->der!=NULL) { ultimo=actual; actual=actual->der; } ultimo->der=NULL; delete actual; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

106

recorreder(primer); recorreizq(ultimo); return primer; } //para eliminar cualquier dato que desee nodo *elimina_cualquier(nodo *primer) { double dato; nodo *actual,*anterior,*ultimo,*pu; char b='v'; cout<<"DIGITE EL NUMERO A ELIMINAR: "; cin>>dato; actual=primer; //busca el dato y trae la direccion del nodo anterior while(actual->info!=dato && b=='v') { if(actual->der!=NULL) { anterior=actual; actual=actual->der; pu=actual; } else { b='f'; } } pu=actual->der; //si encontro el dato if(actual->der==NULL&&actual->info==dato) { //si solo hay un nodo if(actual->der==NULL&&actual->izq==NULL) { primer=NULL; delete primer;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

107

recorreder(primer); recorreizq(primer); return primer; } else //si es el ultimo nodo { anterior->der=NULL; delete actual; recorreder(primer); recorreizq(anterior); return primer; } } //si no encontro ningun nodo //pu=q->der; if(b=='f') { cout<<endl<<endl<<endl; cout<<"ERROR "<<endl; cout<<"EL NUMERO NO EXISTE EN LA LISTA "<<endl; cout<<"LA LISTA SIGUE QUEDANDO IGUAL "<<endl; cout<<endl<<endl; recorreder(primer); recorreizq(actual); return primer; } else { //si es el primero de la lista if(primer==actual) { primer=actual->der; primer->izq=NULL; ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

108

//si no es el primero de la lista y est entre otros dos nodos else { anterior->der=pu; pu->izq=anterior; ultimo=primer; while(ultimo->der!=NULL) { ultimo=ultimo->der; } } delete actual; recorreder(primer); recorreizq(ultimo); return primer; } }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

109

4.

ALGORITMOS DE ORDENAMIENTO

4.1. BURBUJA MEJORADO 4.2. MTODO SHELL 4.3. QUICKSORT

Los algoritmos de ordenamiento permiten arreglar una estructura de datos como un vector, una matriz, o un conjunto de registros en algn orden secuencial de acuerdo a un criterio determinado. El objetivo del ordenamiento en cualquier estructura de datos es facilitar las bsquedas de alguno de los elementos en dicha estructura. Ordenar los elementos de las estructuras de datos consiste en mover los datos o sus referencias de tal manera que queden en una secuencia ya sea numrica, alfabtica en orden ascendente o descendente. Existen dos tipos de algoritmos de ordenamiento: los internos y los externos. Los internos son aquellos que se utilizan cuando los elementos a ordenar se encuentran en la memoria principal del computador. Entre los internos se encuentran: Insercin directa, insercin binaria, seleccin directa, burbuja, shake, shell, heap, tournament, quick sort, merge sort y radix sort. Los externos se utilizan cuando los datos estn en memoria secuendaria o lugares externos como discos duros, diskettes, cintas magnticas entre otros. Entre ellos se encuentran: Straight merging, natural merging, balanced multiway merging, polyphase sort, distribution of initial runs. La eficiencia de un algoritmo de ordenamiento se mide por el nmero de comparaciones o el nmero de movimientos de items. Un algoritmo es bueno cuando este requiere de nlogn comparaciones, donde n es el nmero de elementos a ordenar. A continuacin se explicarn algunos de los algoritmos de ordenamiento internos.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

110

4.1.

BURBUJA MEJORADO

El mtodo burbuja mejorado es ms eficiente que el mtodo burbuja clsico. La diferencia radica en que el mejorado utiliza una bandera que indica cuando el vector ya se encuentra ordenado, mientras que el clsico no utiliza ninguna bandera. Una prueba de escritorio para este algoritmo es el siguiente: El nmero de elementos del vector es n = 3, las variables comienzan con los valores: aux=0 J=1 band=f El vector inicial es el siguiente: 5 8 4

Entra el algoritmo al while y se pregunta si J = 1 es menor que n = 3, adems, si la bandera es falsa, como se cumplen las dos condiciones, entonces, se hace band =v y entra al for j= 0, se pregunta si a(0) > a(1), como no es verdadero, entonces j=1 , se pregunta si a(1) > a(2), como es verdadero, entonces, se intercambian los valores 8 y 4 aux=8 a[1]=4 a[2]=8 El vector queda as: 5 4 8

Se hace, band=f y se incrementa nuevamente J=2 Nuevamente, entra el algoritmo al while y se pregunta si J = 2 es menor que n = 3, adems, si la bandera es falsa, como se cumplen las dos condiciones, entonces, se hace

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

111

band =v y entra al for j=0, se pregunta si a(0) > a(1), como es verdadero, entonces se intercambian los valores 5 y 4 aux=5 a[0]=4 a[1]=5 El vector queda as: 4 5 8

Se hace, band=f y se incrementa nuevamente j j=1 , se pregunta si a(1) > a(2), como no es verdadero, entonces, se sale del if y se incrementa J=3 Nuevamente, entra el algoritmo al while y se pregunta si J = 3 es menor que n = 3, adems, si la bandera es falsa, como no se cumple las primera condicin, entonces, se sale del while y se imprime el vector ya ordenado. Ejemplo 38. Programa Burbuja mejorado /* programa burbuja mejorada o con seal*/ #include<conio.h> #include<stdio.h> #include<stdlib.h> #include<iostream.h> void main() { int J,j,aux; char band; int n, a[10]; J=1; band='f'; n=5; for(j=0;j<n;j++) { cout<<"digite un nmero:\t"; cin>>a[j];

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

112

while((J<n)&&(band=='f')) { band='v'; for(j=0;j<n-1;j++) { if(a[j]>a[j+1]) {aux=a[j]; a[j]=a[j+1]; a[j+1]=aux; band='f'; } } J=J+1; } cout<<"el vector ordenado es:\n"; for(j=0;j<n;j++) { cout<<a[j]<<"\n"; } getch(); } 4.2. MTODO SHELL

El mtodo SHELL es uno de los mtodos de ordenamiento ms eficientes y es una versin mejorada del mtodo de insercin directa. Recibe el nombre de mtodo SHELL en honor a su autor, DONALD L. SHELL, quien lo propuso en 1959. Este mtodo tambin se conoce como Mtodo de Insercin con Incrementos Decrecientes. Shell propone que las comparaciones entre elementos se efecten con saltos de mayor tamao pero con incrementos decrecientes. As, los elementos quedarn ordenados en el arreglo ms rpidamente. Inicialmente, se tiene un vector desordenado:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

113

Entonces, se forman parejas tomando un salto de tamao 4 y se comienzan las comparaciones entre el primer nmero del vector y el quinto, el segundo y el sexto, el tercero y el sptimo y asi sucesivamente. Si se desea ordenar el vector de menor a mayor y al realizar la comparacin el primer elemento de la pareja es mayor que el segundo elemento, se realiza el intercambio a travs de un temporal. El nuevo vector en una primera iteracin quedar as: 5 1 2 3 7 4 8 6

Ahora se realizan saltos de tamao 2 y se realizan comparaciones entre el primer y el tercer nmero, el segundo y el cuarto, el tercero y el quinto, el cuarto y el sexto, el quinto y el sptimo, el sptimo y el octavo. 7 1 8 6 5 4 2 3

El nuevo vector queda as: 7 1 5 4 2 3 8 6

Nuevamente, se realizan comparaciones entre elementos cuyo salto sea 2 hasta que no existan ms intercambios. El vector queda as:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

114

Ahora, se realizan comparaciones entre elementos cuyo salto es 1: 5 1 2 3 7 4 8 6

El nuevo vector queda as: 1 2 3 5 4 7 6 8

Se realizan nuevamente comparaciones entre elementos contiguos hasta que el vector quede ordenado: 1 2 3 5 4 7 6 8

Finalmente, el vector queda ordenado: 1 2 3 4 5 6 7 8

Ya en el cdigo de SHELL, se definen variables como por ejemplo, n que indica el tamao del vector, a es el vector de elementos enteros; i,j,k son variables que indican posiciones dentro del vector; auxi es la variable temporal que permite el intercambio de elementos en caso de requerirse y salto es la variable de tipo entero que contiene el tamao del salto para conformar la pareja de elementos.

int int int int

n; a[20]; i,j,k,auxi; salto;

Inicialmente, la variable salto toma la parte entera de la mitad del tamao del vector mediante las lneas:

cout<<"por favor digite el tamao de la lista\n"; cin>>n; salto= int((n)/2);

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

115

Una vez se han declarado e inicializado las variables, se llena el vector y se procede a ordenar el vector. Este mtodo consiste en formar parejas de nmeros teniendo en cuenta el salto que inicialmente corresponde a la mitad del tamao del vector. Los elementos de una pareja se comparan entre s, y si es necesario se realiza el intercambio de los valores utilizando para esto una variable temporal llamada auxi. El tamao del salto cambia solamente si en el salto anterior ya no se pueden realizar ms intercambios. El ordenamiento termina cuando el salto tiene el valor de cero. La parte de cdigo que se encarga de realizar el ordenamiento shell es el siguiente: Ejemplo 39. Algoritmo ordenamiento SHELL while(salto>0) {for(i=salto;i<n;i++) {j=i-salto; while(j>=0) { k=j+salto; if (a[j]<= a[k]) j=-1; else { auxi=a[j]; a[j]=a[k]; a[k]=auxi; j=j-salto; } } } salto=int(salto/2); }

A continuacin, el programa completo del ordenamiento SHELL: Ejemplo 40. Programa completo del mtodo de ordenamiento SHELL #include<stdio.h> #include<conio.h> #include<iostream.h>

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

116

void main() { int n; int a[20]; int i,j,k,auxi; int salto; cout<<"por favor digite el tamao de la lista\n"; cin>>n; salto= int((n)/2); for(i=0;i<n;i++) { cout<<"digite el nmero "<<i+1<<" = " ; cin >>a[i]; } while(salto>0) { for(i=salto;i<n;i++) {j=i-salto; while(j>=0) { k=j+salto; if (a[j]<= a[k]) j=-1; else { auxi=a[j]; a[j]=a[k]; a[k]=auxi; j=j-salto; } } }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

117

salto=int(salto/2); } cout<<"LA LISTA ORDENADA ES:\n"; for(i=0;i<n;i++) { cout<<a[i]<<"\n"; } getch(); } 4.3. QUICKSORT

Este algoritmo desarrollado por Tony Hoare se basa en particionar la lista a ordenar en varias sublistas. El mtodo consiste en dividir la lista en 2 partes separadas por un elemento: una particin izquierda, un elemento central denominado pivote, y una particin derecha. El pivote es un elemento de particin que puede ser el primero, el ltimo o en el mejor de los casos el elemento que divida exactamente por la mitad la lista. La idea es ubicar en la particin izquierda todos los elementos menores que el pivote y los elementos mayores al pivote en la particin derecha. Cada sublista se ordena independientemente y de manera recursiva utilizando el mismo algoritmo; es decir, se llama sucesivamente al propio algoritmo Quicksort. La lista final ordenada se consigue uniendo la primera sublista, el pivote y la segunda lista, en ese orden, en una nica lista.

La parte de cdigo que determina quien es el pivote, requiere de la posicin inicial y el tamao de la lista, o la posicin final de la lista. int pivot = a[(inf + sup) / 2]; En la primera divisin del vector ejemplo, inf inicialmente tiene el valor de 0 y sup tiene el valor de 9. Entonces, pivote tiene el valor de a[9/2] = a[4] = 3. pivote 64 68 8 82 25 28 41 74 35 59 i j

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

118

El indice i se ubica en el elemento 41 y el indice j se ubica en el elemento 28. El algoritmo incrementar el ndice i siempre y cuando el elemento de la lista sea menor que el pivote y decrementar el ndice j si el elemento es mayor que el pivote. Entonces, para el ejemplo, se pregunta si 41 es menor que 64, y como es cierto, se incrementa i. Se pregunta si 74 es menor que 64, como no es cierto i queda en esa posicin. De igual forma, se pregunta si 28 es mayor que 64, y como no es cierto, no se decrementa el ndice j. pivote 64

41

74

35

59

68

82

25

28

i j Ahora se pregunta si i es menor o igual a j, como esto es cierto, se realiza el intercambio, incrementndose i y decrementndose j. El vector queda as: pivote 64

41

28

35

59

68

82

25

74

i j An se contina en el do while, ya que i es menor que j. Nuevamente, se pregunta si el elemento en el ndice i es menor que el pivote, es decir, 35 es menor que 64, y como es cierto se incrementa i. pivote 64 68 8 82 25 74 41 28 35 59 i j

Se pregunta si 59 es menor que 64, como es cierto se incrementa i. De igual forma, se pregunta si el elemento en el ndice j es mayor que el pivote, es decir, 25 es mayor que 64, como no es cierto, j no se decrementa y queda en la misma posicin. pivote 64 i

41

28

35

59

68

82

25 j

74

Ahora, se pregunta si i es menor que j, y como es cierto, se realiza el intercambio, se incrementa i y se decrementa j. El vector resultante es:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

119

41

28

35

59

25

68 i

82 j

pivote 64

74

An se contina en el do while, ya que i es menor que j. Nuevamente, se pregunta si el elemento en el ndice i es menor que el pivote, es decir, 68 es menor que 64, y como no es cierto, i queda igual. Se pregunta si el elemento en el ndice j es mayor que el pivote, como es cierto, se decrementa j. pivote 41 28 35 59 25 68 8 82 64 74 i j

Nuevamente, se pregunta si el elemento en j es mayor que el pivote, y como no es cierto, j queda igual. Se intercambian los elementos, i se incrementa y j se decrementa. El vector resultante es: pivote 64

41

28

35

59

25

8 j

68 i

82

74

Se sale del do while, ya que no se cumple la condicin de i menor o igual a j. Ahora, se pregunta si inf 0 es menor que j 5, y como se cumple entonces la primera sublista va desde el elemento 0 al elemento 5. Por ltimo, se pregunta si i 6 es menor que el ndice sup 9. Como es cierto, la segunda sublista va desde el elemento en la posicin 6 hasta la posicin 9. As, primera sublista 41 28 inf segunda sublista 68 82 64 i

35

59

25 j

74 sup

Ahora, se toma la primera sublista y se aplica el mismo procedimiento OrdRap. pivote 35

41 i

28

59

25

8 j

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

120

Se pregunta si 41 es menor que 35, como no es cierto i queda igual. Se pregunta si 8 es menor que 35, como no es cierto j tambien queda igual. Como i es menor que j, se intercambian los elementos, se incrementa i y se decrementa j. La primera sublista queda as: pivote 35

28 i

59

25 j

41

An se contina en el do while, ya que i es menor que j. Nuevamente, se pregunta si 28 es menor que 35, como es cierto se incrementa i. Se pregunta si 35 es menor que 35, como no es cierto, i queda igual.

28

pivote 35 i

59

25

41 j

Se pregunta si 41 es mayor que 35, como es cierto, se decrementa j. Se pregunta si 25 es mayor que 35, como no es cierto, j queda en la posicin del elemento 25. pivote 8 28 35 59 25 41 i j Se pregunta si i es menor que j, como es cierto, se intercambian los elementos, se incrementa i y se decrementa j. La primer sublista queda as: pivote 8 28 25 59 35 41 ij An se contina en el do while, ya que i es igual a j. Se pregunta nuevamente, si 59 es menor que 35, como no es cierto i no se incrementa. Se pregunta si 59 es mayor que 35, como es cierto, se decrementa j. pivote 35 41 8 28 25 59 j i Ahora, se pregunta si 25 es mayor que 35, como no es cierto, j queda igual. Como j es mayor que i, se sale del do while, y ahora se generan nuevas sublistas.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

121

En la siguiente sublista se aplica nuevamente el procedimiento OrdRap, hasta que la sublista es de un solo elemento: pivote 28

8 Se ordena la sublista y queda as: 8

25

25

pivote 28

En la otra sublista se aplica tambien el procedimiento OrdRap: pivote 35 41 59 i j Se pregunta si 59 es menor que 35, como no es cierto, i queda igual. Se pregunta si 41 es mayor que 35, como es cierto, se decrementa j. Se pregunta si 35 es mayor que 35, como no es cierto, j queda igual. pivote 35 41 59 i j Como i es menor que j, se intercambian los elementos, incrementndose i y decrementndose j. La sublista resultante es: pivote 35 59 41 j i Como j es mayor que i, se sale del do while. Se aplica el procedimiento OrdRap a las siguientes sublistas: 35 59 41

El elemento 35 queda igual, y se ordena la otra sublista, es decir, se intercambia el 59 y el 41. La sublista ordenada queda as: 35 41 59

Entonces, la primera sublista ya ordenada, queda as:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

122

25

primera sublista 28 35

41

59

Ahora, se aplica el procedimiento OrdRap a la segunda sublista: pivote 68 82 64 74 i j Se pregunta si 68 es menor que 82, como se cumple, i se incrementa. Se pregunta si 74 es mayor que 82, como no se cumple, j queda igual. pivote 82 i

68

64

74 j

Se intercambian los elementos, se incrementa i y se decrementa j. La sublista queda as: pivote 82 68 74 64 i j Se contina en el do while, ya que i es igual a j. Se pregunta si 64 es menor que 82, como es cierto i se incrementa. Ahora se pregunta si 64 es mayor que 82, y como no es cierto, j queda igual. pivote 68 74 64 82 j i Como j es mayor que i, se sale del do while y se forman dos sublistas. 68 74 64 82

La sublista del elemento 82, queda igual. A la otra sublista, se le aplica el procedimiento OrdRap y queda as: 64 68 74

La segunda sublista ordenada, queda finalmente:

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

123

segunda sublista 64 68 74 Por ltimo, la lista complementamente ordenada: 8 25 28 35 41 59

82

64

68

74

82

A continuacin, el programa completo del ordenamiento QUICKSORT: Ejemplo 41. Mtodo de ordenamiento QUICKSORT #include <conio.h> #include <stdio.h> #include <iostream.h> int a[10], n, k; void OrdRap(int lista[10],int inf, int sup) {// Inicializacin de variables int temp, i, j; i = inf; j = sup; int pivote = lista[(inf + sup) /2]; // Clasificamos la sublista do { while (lista[i] < pivote)i++; while (lista[j] > pivote)j--; if (i <= j) { temp = lista[i]; lista[i] = lista[j]; lista[j] = temp; i++; j--; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

124

} while (i<=j); //se aplica nuevamente el procedimiento a cada sublista if (inf < j) OrdRap (lista, inf, j); if (i < sup) OrdRap (lista, i , sup); } void main() { cout<<"digite cantidad de elementos del vector"; cin >> n; for (k=0;k<n;k++) {cout<< "digite un elemento : "; cin >> a[k]; cout<<"\n"; } OrdRap(a,0,n-1); cout<< "vector ordenado\n"; for (k=0;k<n;k++) { cout<< "elemento : "<< a[k]; cout<<"\n"; } getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

125

5. ALGORITMOS DE BSQUEDA

5.1. 5.2.

BSQUEDA BINARIA BSQUEDA SECUENCIAL

5.1.

BSQUEDA BINARIA

En una lista ordenada, este mtodo busca el elemento central de la lista inicial, toma el valor a buscar y lo compara con el elemento central. Si el nmero buscado es menor que el elemento central, entonces se forma una nueva lista con los nmeros anteriores al elemento central, repitindose nuevamente este proceso. Si el elemento buscado es mayor que el elemento central, entonces, se forma una nueva lista pero con los nmeros posteriores al elemento central, repitindose nuevamente dicho proceso. Inicialmente, se declaran variables como:

x es el vector de nmeros enteros; num es el elemento a buscar; i es la variable que indica la posicin en el vector; bajo es la variable que indica la posicin del primer elemento; alto es la variable que indica la posicin del ltimo elemento; y central indica
la posicin del elemento central. El vector inicial ordenado es: 55 56 57 58 59 60 61 62 63 64

bajo

central

alto
bajo se

Y se supone que el elemento a buscar es el nmero 57. Para el ejemplo, inicializa en 1, alto es igual a 10 y central es igual a 5. Primera sublista: Como 57 < 59, entonces la nueva lista es : 55 56 57 58

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

126

bajo

central

alto

Aqu, bajo es igual a 1, alto es igual a 4 y central es igual a 2. Segunda sublista: Como 57 > 56, entonces la nueva lista es: 57 58

bajo central

alto

Aqu, bajo es igual a 1, alto es igual a 2 y central es igual a 1. Aqu, el elemento buscado, es decir, 57, es el elemento central. Por lo tanto, el elemento fue encontrado. Ejemplo 42.Mtodo de bsqueda binaria #include<stdio.h> #include<conio.h> #include<iostream.h> const n=7; void main () {int x[10], num, i; int bajo=1; int alto=n; int central=(int((bajo+alto)/2)); cout << "INGRESE EL NUMERO A BUSCAR: "; cin >>num; for (i=0; i<n; i++) { cout<<"LLENAR EL VECTOR: "; cin>>x[i]; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

127

while ( (bajo <= alto) && (x[central]!=num)) { if (num<x[central]) alto = central-1; else bajo = central+1; central=((int(bajo+alto))/2); } if (num==x[central]) cout<<"VALOR ENCONTRADO: "<<x[central]<<"POSICIN: "<<central; else cin>> "VALOR NO ENCONTRADO"; getch (); } 5.2. BUSQUEDA SECUENCIAL

Este mtodo permite encontrar un elemento dentro de un vector ya ordenado. Si x es el elemento que se desea buscar, ste se compara con todos y cada uno de los elementos del vector. El mtodo funciona de la siguiente manera: Para i = 0 55 56 57 58 59 60 61 62 63 64

55>57?
Para i = 1 55 56 57 58 59 60 61 62 63 64

56 >57?

Para i = 2

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

128

55

56

57

58

59

60

61

62

63

64

57 >57?
Aqu termina el ciclo while y se imprime la posicin del elemento encontrado. Ejemplo 43. Mtodo de bsqueda secuencial # include <stdio.h> # include <conio.h> # include <iostream.h> void main () { int i, x, n, a[20]; cout<<"digite el tamao del vector\n"; cin>>n; cout<<"digite el numero a buscar\n"; cin>>x; for (i=0; i<n; i++) {cout<<"digite los nmeros para el vector\n"; cin>>a[i]; } //si esta de mayor a menor x<a[i] i=0; while ((i<=n)&& (x>a[i]))//si esta en desorden x!=a[i] { i++; } if((i>n )||( x< a[i])) { cout<<"el elemento no esta en el vector "; } else { cout<<"el numero esta en la posicin "<<i; }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

129

getch (); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

130

6. PROGRAMACIN ORIENTADA A OBJETOS

6.1.

DEFINICIN DE REQUISITOS DE UN SISTEMA

Para poder implementar un programa orientado a objetos POO, inicialmente se identifican los requisitos del programa y los actores o usuarios finales que interacturn directamente o indirectamente con el sistema a desarrollarse. En el diagrama de Casos de Uso, segn el lenguaje unificado de modelado UML, mostrado en la figura 31, se visualizan los actores (muecos) y los casos de uso u objetivos que tienen los actores sobre el sistema (elipses). Slo se tomar un caso de uso de varios casos de uso propios de un sistema acadmico de un colegio. Para el ejemplo, se toma el caso de uso administrar estudiantes que consiste en la creacin de nuevos estudiantes y en consultar los datos de los estudiantes. Quien directamente acta sobre este sistema es la secretaria acadmica quien se encarga de crear nuevos estudiantes cuando ingresan al colegio o consultar los datos cuando los necesite. E indirectamente quien acta sobre el sistema es el estudiante quien brinda la informacin a la secretaria acadmica para completar el caso de uso administrar estudiantes. Figura 31. Caso de Uso administrar estudiantes

Administrar estudiantes

Secretaria acadmica

Estudiante

Una vez se han identificado los objetivos de los actores sobre el sistema, se procede a realizar un anlisis y diseo del sistema, en una o varias fases. Por ejemplo, la metodologa Rational Unified Process (RUP) de IBM, propone realizar estas disciplinas en 4 fases: inicio, elaboracin, construccin y transicin. En este texto, no se hablar de esta metodologa, pues no es la intencin.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

131

En la etapa de anlisis se realiza un modelo de anlisis de clases o modelo del dominio, es decir, se identifican las entidades reales (clases) junto con sus atributos y asociaciones del sistema. En la etapa de diseo se realiza el modelo de diseo de clases, identificando los mtodos de las clases y definiendo la arquitectura del sistema. Una vez se tienen diseados los componentes que pueden ser una clase o un conjunto de clases, se implementan en un lenguaje de programacin orientado a objetos. 6.2. DEFINICIN DEL DOMINIO DE UN SISTEMA

Para modelar el dominio de un sistema se definen las entidades del sistema, identificando las clases del sistema a desarrollar con sus atributos y asociaciones, en la disciplina de anlisis; y en la disciplina de diseo se identifican los mtodos. 6.2.1. Objetos y Clases

Un objeto es algo que puede ser tangible o intangible. Todo objeto tiene unas caractersticas propias: tiene una identidad, es decir un nombre que lo identifica como nico tiene unos atributos o propiedades que los caracteriza

Una clase es una coleccin de objetos. Todo objeto pertenece a una clase o es una instancia de una clase. En C++ tanto los datos como las funciones y procedimientos (miembros de la clase) se renen en lo que se llama Clase. Una clase se puede definir mediante la sintaxis: CLASS nombre_clase { datos y funciones privados; public: datos y funciones pblicos; funcin constructora; funcin destructora; }; Una clase est formada por miembros: datos y funciones que pueden ser de tipo: Privados o private: miembros que pueden ser usados por funciones de la clase.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

132

Pblicos o public: miembros que pueden ser usados por funciones de otras clases. Protegidos o protected: miembros que pueden ser usados por funciones de clases derivadas o hijas. Las funciones de una clase se denominan MTODOS. En UML, una clase se representa mediante un cuadro indicando el nombre de la clase, sus atributos y mtodos, como se observa en la figura 32. El smbolo + que antecede a un atributo o mtodo indica que el miembro de la clase es pblico, el smbolo - indica que es privado y el smbolo # indica que es protegido. Figura 32. Clase en UML
ESTUDIANTE - Cedula : entero - Nombres: cadena(30) - Apellidos: cadena(30) +crearNuevo() +mostrarDatos() Nombre clase atributos

mtodos

La definicin de una clase en C++ se implementa en el archivo de tipo header estudiante.h as: Ejemplo 44. Definicin de la clase estudiante class Estudiante { public: CrearNuevo(); MostrarDatos(); private: int cedula; char Nombres[30];

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

133

char Apellidos[30]; }; 6.2.2. Mtodos de una clase

Los mtodos de un objeto son las operaciones que realizan los objetos de una clase. Se definen los mtodos para implementar el algoritmo necesario que procesa los datos de una clase o su interaccin con otras. La sintaxis para definir los mtodos en una clase es la siguiente: Nombre_Clase::Nombre_Mtodo() { definicin del mtodo } En el archivo estudiante.cpp se definen las acciones o mtodos del objeto estudiante como es crear nuevo estudiante y mostrar los datos de un estudiante. Ejemplo 45. Implementacin de los mtodos de la clase estudiante include "estudiante.h" #include <iostream.h> Estudiante::CrearNuevo() { cout <<"digite nmero de cedula"; cin >> cedula; cout <<"digite nombre"; cin >> Nombres; cout <<"digite apellido"; cin >> Apellidos; } Estudiante::MostrarDatos() {cout<<endl; cout <<"Cedula estudiante"<<cedula<<endl; cout <<"Nombres"<<Nombres<<endl;

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

134

cout <<"Apellidos"<<Apellidos<<endl; } 6.2.3. Llamada de datos y funciones (Mtodos)

Los mtodos se llaman desde el programa principal utilizando el nombre del mtodo separado de un punto del nombre de la clase, as: Nombre_clase.Nombre_mtodo(); El archivo principal.cpp tiene las siguientes instrucciones que muestran como se llaman los mtodos crear nuevo estudiante y mostrar los datos de un estudiante: Ejemplo 46. Llamada de los mtodos de una clase #include "estudiante.cpp" #include "iostream.h" #include "conio.h" Estudiante est; void main() { est.CrearNuevo(); est.MostrarDatos(); getch(); } 6.2.4. Mtodos de acceso

El acceso a los datos privados de una clase se puede hacer mediante el uso de funciones miembro conocidas como funciones de acceso o mtodos de acceso. Los dos mtodos de acceso son GET y SET. El mtodo de acceso GET, permite leer datos privados de esa clase. El mtodo de acceso SET, permite modificar o sobreescribir los datos privados de una clase. A continuacin se muestra un programa que permite definir las coordenadas x, y de un vector en el plano cartesiano. El mtodo set_vector_plano es un mtodo que recibe dos parmetros enteros correspondientes a las coordenadas x, y del vector en el

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

135

plano, y consta de dos instrucciones x=a; y = b, utilizadas para asignar los parmetros a y b a las coordenas x, y. El mtodo get_vector_plano permite tener acceso a los datos miembro de la clase vector_plano. En este mtodo se muestran los datos miembros en pantalla, es decir, se imprimen las coordenadas del vector. Ejemplo 47. Mtodos SET y GET #include <conio.h> #include <iostream.h> class vector_plano{ int x, y; public: void set_vector_plano(int a, int b); void get_vector_plano(); }; void vector_plano::set_vector_plano(int a, int b) { x = a; y = b; } void vector_plano::get_vector_plano() { cout<<"\ncoordenada x= "<<x; cout<<"\ncoordenada y= "<<y; } void main(void) { vector_plano v1, v2; v1.set_vector_plano(3,4); cout<<"\nvector 1\n"; v1.get_vector_plano(); v2.set_vector_plano(5,2); cout<<"\nvector 2\n"; v2.get_vector_plano(); getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

136

6.2.5.

Mtodos constructores y destructores

Son mtodos predefinidos por el compilador. Los mtodos constructores se llaman implcitamente, cuando se crean los objetos de esa clase. El mtodo constructor sirve para reinicializar los datos en cero, NULL o asignar memoria y debe llevar el mismo nombre de la clase si ste se define explcitamente por el programador. No es necesario crear el mtodo constructor, pero si ste no existe, el compilador reinicializa los datos de la clase, por defecto. La sintaxis para definir el mtodo constructor es la siguiente: Nombre_Clase::Nombre_Clase() { definicin del mtodo constructor } Ejemplo 48. Mtodo constructor Class punto { int x, y; Public: crear_punto(int x, int y); } punto::punto() {x=0; y=0; } Los mtodos destructores tampoco al igual que los constructores, se deben llamar explcitamente. Si no existe, el compilador llama uno por defecto antes de terminar el programa. Este mtodo permite liberar memoria si sta ltima, se ha asignado previamente. Tanto los mtodos constructores como los destructores no retornan ningn valor.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

137

La sintaxis para definir el mtodo constructor es la siguiente: Nombre_Clase::Nombre_Clase() { definicin del mtodo destructor } 6.2.6. Composicin de clases

Una clase puede tener como miembro otras clases. Cuando se declara un objeto de una clase, y esta tiene otras clases como miembro, primero se construyen los objetos de la clase miembro antes que los objetos de la clase que los contienen. 6.2.7. Sobrecarga de Operadores

En clases, la sobrecarga de operadores permite definir una operacin como +, - *, / entre los objetos de varias clases. La sintaxis para definir funciones sobrecargadas es: tipo_de_objeto_devuelve nombre_clase::operator(parmetros)

A continuacin se muestra un programa que permite sumar dos vectores del plano cartesiano en dos dimensiones. Ejemplo 49. Sobrecarga de operadores #include <conio.h> #include <iostream.h> class vector_plano{ int x, y; public: vector_plano(); vector_plano vector_plano::operator+(vector_plano); void set_vector_plano(int a, int b); void get_vector_plano(); }; vector_plano vector_plano::operator+(vector_plano v) {

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

138

x = x + v.x; y = y + v.y; return( *this ); } void vector_plano::set_vector_plano(int a, int b) { x = a; y = b; } vector_plano::vector_plano() { x = 0; y = 0; } void vector_plano::get_vector_plano() { cout<<"\ncoordenada x= "<<x; cout<<"\ncoordenada y= "<<y; } void main(void) { vector_plano v1, v2, v3; v1.set_vector_plano(3,4); cout<<"\nvector 1\n"; v1.get_vector_plano(); v2.set_vector_plano(5,2); cout<<"\nvector 2\n"; v2.get_vector_plano(); v3 = v1 + v2; cout<<"\nvector 3 o resultante\n"; v3.get_vector_plano(); getch(); }

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

139

Este ejemplo de mtodo de sobrecarga de operadores, recibe como parmetro un vector del plano cartesiano permitiendo sumar dos vectores y devolviendo un vector resultante al void principal. vector_plano vector_plano::operator+(vector_plano v) { x = x + v.x; y = y + v.y; return( *this ); } Cuando se ejecuta la instruccin v3 = v1 +v2, el compilador transforma v1 + v2 en v1.operator + (v2). En la funcin, se reemplaza v por v2 as: x = x + v2.x y = y + v2.y Las coordenadas x y y corresponden al vector v1 quien es el objeto que llama a la funcin. El objeto por defecto es el que queda a la izquierda del operador (v1) y el objeto que normalmente se suele pasar es el de la derecha (v2). La palabra reservada this, es un puntero al objeto por defecto, es decir, al objeto que llama la funcin, en este caso, v1. Se utiliza *this para devolver el contenido de v1, no el puntero. 6.2.8. Funciones amigo y clases amigo

En C++ se pueden definir funciones y clases amigo de una clase para tener acceso a los datos y funciones miembro privados de esa clase. Para declarar una funcin amigo de una clase, se precede la palabra reservada friend a la funcin. La sintaxis para definir funciones amigas de una clase es la siguiente: friend tipo_de_objeto_devuelve nombre_funcion(parmetros)

Tambin se pueden definir funciones homnimas como amigos de una clase.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

140

Ejemplo 50. Funciones amigas #include <conio.h> #include <iostream.h> class vector_plano{ int x, y; public: vector_plano(); friend vector_plano operator+(int, vector_plano); void set_vector_plano(int a, int b); void get_vector_plano(); }; vector_plano operator+(int num, vector_plano v) { vector_plano h; h.x = num + v.x; h.y = num + v.y; return(h); } void vector_plano::set_vector_plano(int a, int b) { x = a; y = b; } vector_plano::vector_plano() { x = 0; y = 0; } void vector_plano::get_vector_plano() { cout<<"\ncoordenada x= "<<x; cout<<"\ncoordenada y= "<<y; } void main(void)

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

141

{ int num; vector_plano v2, v3; cout<<"digite un entero"; cin>>num; v2.set_vector_plano(5,2); cout<<"\nvector 2\n"; v2.get_vector_plano(); v3 = num + v2; cout<<"\nvector 3 o resultante\n"; v3.get_vector_plano(); getch(); } En el ejemplo, la funcin amiga, permite sumar un nmero entero num con un vector: vector_plano operator+(int num, vector_plano v) { vector_plano h; h.x = num + v.x; h.y = num + v.y; return(h); } Al llamarse la funcin con la instruccin v3 = num + v2, el compilador la convierte en: v3 = num.operator + (v2) Es decir, num se convierte en un objeto y de esta forma se puede sumar cada una de las coordenadas del vector con el nmero entero. La funcion amiga recibe como parmetros el nmero entero y el vector v, el cual se reemplaza por v2. Entonces, la instruccin h.x = num + v.x se convierte en: v3.x = num + v2.x; Finalmente, la funcin retorna el vector v3 resultante al void principal.

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

142

6.3. COMPONENTES DEL SISTEMA

La implementacin de una clase en C++ se realiza a travs de 3 archivos: - El primero es el archivo de tipo header o encabezado *.h, el cual permite definir la clase, all se identifican los atributos y los mtodos de los objetos de dicha clase. - El segundo archivo *.cpp permite implementar los mtodos de la clase. - El tercer archivo *.cpp permite llamar los mtodos de una clase, en el void main. La dependencia entre estos archivos se observa en la figura 33, mediante un diagrama de componentes segn UML. El diagrama de componentes tiene dos elementos bsicos: la caja que indica un componente y la flecha que indica de quien se depende. Se lee as: A depende de B, si A B. Figura 33. Estructura de una clase en C++
estudiante.h
<<usa>>

estudiante.cpp

<<usa>>

Principal.cpp

Estructuras de Datos en C++ Luisa Mireya Rojas Mendoza

143

7. BIBLIOGRAFA

JOYANES AGUILAR, Luis. Programacin en C++, Editorial McGraw-Hill, 2000. JOYANES AGUILAR, Luis; ZAHONERO, Ignacio. Programacin en C: Metodologa, algoritmos y estructura de datos, 2 edicin, Editorial McGraw-Hill, 2005. LARMAN, Craig. UML y Patrones. Una introduccin al anlisis y diseo orientado a objetos y al anlisis y diseo orientado a objetos y al proceso unificado. Editorial Prentice may, 2 edicin, Madrid, Espaa, 2003. STEVENS, Perdita; POOLEY, Rob. Utilizacin de UML en Ingeniera del Software con Objetos y Componentes. Pearson Educacin S.A. Madrid, Espaa, 2002. LEN PEREIRA, Jos J. Lenguaje C. Universidad Industrial de Santander. Ingeniera de Sistemas. Ediciones UIS. Bucaramanga, Colombia, 1995. Manual Bsico de Programacin en C++. Disponible en << >> Programacin en C++. <<http://ctc.aspira.org/PDF%20files/cplus.pdf>> Disponible en

http://www.bairesrobotics.com.ar/poo/Manual%20Programaci%F3n%20C++.pdf

Estructuras de datos. Disponible <<http://es.wikipedia.org/wiki/Estructura_de_datos>> Disponible http://www.itlp.edu.mx/publica/tutoriales/estru1/index.htm>> Tutorial de Estructuras de Datos en C++. en

en

<<

También podría gustarte