ALGORITMOS

Y
ESTRUCTURAS DE DATOS
EN
LENGUAJE C/C++
Humberto Mazuera Párraga

TABLA DE CONTENIDO alfabética
Agente Aprende a Recorrer Laberinto.................................................................
Árboles(esta en archivo separado).....................................................................
Archivos Binarios y de Texto...............................................................................
Búsqueda Binaria: Algoritmo Recursivo para encontrar Elemento en Vector.......
Cadenas de Caracteres........................................................................................
Código ASCII.......................................................................................................
Cola en Arreglo...................................................................................................
Cola como Lista Enlazada....................................................................................
Estadística Básica...............................................................................................
Evaluación de Expresión Algebraica....................................................................
Expresión de Lógica Proposicional.....................................................................
Leer Cadena en Modo Gráfico..............................................................................
Lista de Listas enlazadas y en memoria dinámica...............................................
Lista Doblemente Enlazada.................................................................................
Lista Simplemente Enlazada y Ordenada.............................................................
Listas Enlazadas, Ejercicios de Programación.....................................................
Lógica Proposicional, expresiones......................................................................
MergeSort: Algoritmo Recursivo de Ordenamiento..............................................
Ordenamientos. Comparación Gráfica.................................................................
Paso de Parámetros por Referencia en Funciones...............................................
Pila en Arreglo y Memoria Estática......................................................................
Pila en Lista Enlazada y en Memoria Dinámica....................................................
Polaca. Notación para expresiones algebraicas...................................................
Polaca. Expresión de Lógica Proposicional.........................................................
Puntero a Notas Musicales..................................................................................
Punteros o Apuntadores.....................................................................................
QuickSort............................................................................................................
Recursión............................................................................................................
Torres de Hanoi..................................................................................................
Vector de Punteros a Funciones.........................................................................
Primera Parte

Segunda Parte

Tercera Parte

1

PRIMERA PARTE
PILAS Y COLAS EN ARREGLOS.
RECURSIÓN.
PUNTEROS.
PASO POR REFERENCIA.
CADENAS.
REFUERZO REGISTROS Y ARCHIVOS.
Algoritmos de Ordenamiento.
Primera Parte

Segunda Parte

Tercera Parte

2

Pila en Arreglo
Introducción
Una pila, a un nivel lógico, es una estructura de datos lineal compuesta de
elementos del mismo tipo, en la cual cada uno de ellos solo puede ser insertado y
eliminado por su parte final. La posición final la llamamos cima o también cabeza
de la pila; para darnos una mejor representación (abstracción) de ella su
representación gráfica en el papel la hacemos en forma vertical, con la cima en
la parte de arriba. De esta forma cuando añadamos un nuevo elemento solo podrá
ser colocado en la parte superior, piense en una pila de platos de cocina o en
una pila de libros, los cuales coloque en orden uno encima de otro. Debido a esto
último las pilas también son llamadas listas en las cuales "el último elemento en
entrar es el primero en salir", en inglés el acrónimo LIFO(Last Input, First
Out).
La pila se considera un grupo ordenado de elementos porque estos están
clasificados de acuerdo al tiempo en que estén residiendo en la pila, el elemento
que se elimina de la cabeza es siempre el que lleve menos tiempo en ella. En
resumen una pila es una lista en la cual los elementos solo pueden ser insertados
y eliminados por un extremo de ella, este extremo es llamado la cima. De esta
forma los elementos son eliminados en forma contraria a como fueron insertados.
Las operaciones básicas de insertar y eliminar las llamaremos Meter() y
Sacar() respectivamente, y serán implementadas sobre la estructura de datos
arreglo unidimensional en el presente capítulo.
Una Pila es una estructura de datos que almacena elementos de un tipo
determinado, que sigue la política de que el primer elemento que se extrae (se
‘desapila’) es el último que se introdujo (se ‘apiló’) -primero en salir, ultimo
en entrar (LIFO)-.

3

Pila de Cadena de caracteres.
#include
#include
#include
#include

//PILACHAR.CPP

<iostream.h>
<stdio.h>
<ctype.h>
<string.h>

const int MaxPila=5;
const int LargoCadena=20;
const int PilaVacia=-1;
char Pila[MaxPila][LargoCadena]; //Variables globales
int Cima = PilaVacia;
void meter();
// Definición de prototipos
void sacar();
void EscribirValoresEnPila();
void meter(){
char item[LargoCadena];
if (Cima == MaxPila-1){
cout << "\n\nDesbordamiento. Digite una tecla";
}
else{
cout << "\nDigite elemento (una palabra): ";
cin >> item;
Cima++;
strcpy(Pila[Cima], item);
}
}
void sacar(){
char item[LargoCadena];
if (Cima == PilaVacia)
cout << "\n\nSubdesbordamiento. digite una tecla";
else {
strcpy(item, Pila[Cima]);
cout << "Sacado de la pila: " << item;
Cima--;
}
}
void EscribirValoresEnPila(){
int i;
if (Cima > PilaVacia)
for (i = Cima; i >= 0; i--)
cout << i << ": " << Pila[i] << endl;
else
cout << "Pila está vacía\n";
}
void main(){
char opcion;

4

case 'S' : sacar(). if (Cima == MaxPila-1) cout << "\n\nDesbordamiento. } } Al entrar a la función meter() nos encontramos con: if(Cima == MaxPila-1) -1 == 5-1 es falso vamos para el else. cin >> opcion. Pila[MaxPila][LargoCadena]. si fuera verdadera estaría ya llena la pila. strcpy(Pila[Cima]. } La siguiente es una prueba de ejecución manual del programa PILACHAR.CPP anterior y el cual maneja una pila de cadenas de caracteres: Inicialmente se definen las siguientes constantes y variables: const const const char int MaxPila = 5. 4 3 2 1 0 ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ └────────────────────┘ Cima=PilaVacia. Analicemos primero la función meter(): void meter(){ char item[LargoCadena]. break. item). Digite una tecla". break. switch (toupper(opcion)) { case 'M' : meter(). } } while (opcion != 'T'). S o T: ". cout << "\nPuede introducir en la Pila un máximo de " << MaxPila << " elementos\n". cin >> item. podemos efectuar invocación interactiva de las funciones meter() y sacar(). ┌────┐ │ -1 │ └────┘ A partir de la función principal. A 5 . int LargoCadena = 10. else{ cout << "\nDigite elemento (una palabra): ". main(). Cima++.do{ EscribirValoresEnPila(). int PilaVacía = -1. cout << "Meter Sacar Terminar: digite M.

Cima se incrementa en uno. retornando al sitio donde la función fué invocada. se digitan los caracteres: "Palmira" los cuales son leídos en la variable item. leyendose en la variable item: "Cali". por esto. y se asigna el item digitado a la Cima de la Pila: item ┌────┐ │Cali│ └────┘ 4 3 Cima ┌────┐ │ 0 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ Cali │ └────────────────────┘ A continuación volvamos a invocar la función meter(): Cima no es igual a MaxPila-1.continuación se pide digitar un elemento. en el main(): item ┌───────┐ │Palmira│ └───────┘ 4 3 Cima ┌────┐ │ 1 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Una vez más se invoca meter(): se digita la palabra "Zarzál" y la pila ahora así: item ┌──────┐ │Zarzál│ └──────┘ 4 3 Cima ┌────┐ │ 2 │ └────┘ 2 1 0 queda Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ Zarzál │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Se invoca meter(): se digita la cadena "Toro" y la pila quedará ahora: item ┌────┐ │Toro│ └────┘ 4 3 Cima Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ Toro │ ├────────────────────┤ 6 . se encrementa Cima y se asignan a la Cima de la Pila. o sea una palabra.

aparecerá en pantalla: "Desbordamiento.┌────┐ │ 3 │ └────┘ 2 1 0 │ Zarzál │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Se invoca meter(): se digita la palabra "Jamundí" y la pila queda: item ┌───────┐ │Jamundí│ └───────┘ 4 3 Cima ┌────┐ │ 4 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ Jamundí │ ├────────────────────┤ │ Toro │ ├────────────────────┤ │ Zarzál │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Se invoca meter(): con este caso if (Cima==MaxPila-1) es verdadero. Si invocamos a continuación la función sacar(): void sacar(){ char item[LargoCadena]. } } Inicialmente intrucción if (Cima == PilaVacía) es falsa por esto seguirá el algoritmo en el else. quedando la pila así: item ┌───────┐ │Jamundí│ └───────┘ Pila ┌────────────────────┐ 4 │ │ ├────────────────────┤ 3 │ Toro │ Cima ├────────────────────┤ ┌────┐ 2 │ Zarzál │ │ 3 │ ├────────────────────┤ └────┘ 1 │ Palmira │ ├────────────────────┤ 0 │ Cali │ └────────────────────┘ El elemento que estaba en la posición 4 del vector Pila se ha borrado "lógicamente". Pila[Cima]) y a continuación se decrementa Cima en 1. if (Cima == PilaVacia) cout << "\n\nSubdesbordamiento. cout << "Sacado de la pila: " << item. digite una tecla". en la variable item se asigna el valor que está en la Cima de la Pila por medio de strcpy (item. es decir del dibujo o sea de lo que debemos abstraer está 7 . Pila[Cima]). Cima--. Digite una tecla" y volverá a la función main() del programa. else { strcpy(item.

empero ya como "basura". invoquemos sacar(): item ┌────┐ │Toro│ └────┘ 4 3 Cima ┌────┐ │ 2 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ Zarzál │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Invocamos sacar(): item ┌──────┐ │Zarzal│ └──────┘ 4 3 Cima ┌────┐ │ 1 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ Palmira │ ├────────────────────┤ │ Cali │ └────────────────────┘ Invocamos sacar(): item ┌───────┐ │Palmira│ └───────┘ Cima ┌────┐ │ 0 │ └────┘ de nuevo item ┌────┐ │Cali│ └────┘ Pila ┌────────────────────┐ 4 │ │ ├────────────────────┤ 3 │ │ ├────────────────────┤ 2 │ │ ├────────────────────┤ 1 │ │ ├────────────────────┤ 0 │ Cali │ └────────────────────┘ invoquemos sacar(): 4 3 Cima ┌────┐ │ -1 │ └────┘ 2 1 0 Pila ┌────────────────────┐ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ ├────────────────────┤ │ │ └────────────────────┘ 8 . en realidad la palabra Jamundí sigue en Pila[4].ocurriendo. Ahora. de nuevo.

aparecerá en pantalla el aviso Digite una tecla" y se regresará a la parte principal a 9 . es verdadero. por esto. continuación.if (Cima == PilaVacía) -1 -1 El if anterior "subdesbordamiento.

opcion = toupper( getch() ).h> <iomanip. void sacar(int *P).. void main(){ int opcion. } } void sacar(int *P){ if ( !Cima ) 10 . *Cima = item. Digite una tecla".Pila Implementada con Punteros //PILAPUNT. break. case 'T' : exit(0). cout << "\n\nMeter Sacar Terminar: digite M. cin >> item.){ EscribirValoresEnPila(). } else { if (Cima == NULL) Cima = Pila. int Pila[MaxPila]. } } } void meter(int *P){ int item.h> <stdlib. cout << "\nPuede introducir en la Pila un máximo de " << MaxPila << " elementos ". cout << "\nDigite elemento(un entero): ". break. S o T: ".CPP #include #include #include #include #include <iostream. if (Cima == (P+MaxPila-1)){ cout << "\n\nDesbordamiento.h> <conio.h> <ctype. switch (opcion) { case 'M' : meter(Pila). getch(). case 'S' : sacar(Pila).h> const int MaxPila=5. /*Inicializa Pila*/ else Cima++. for(. //Definición variables globales int *Cima=NULL. void EscribirValoresEnPila(). //Definición de prototipos void meter(int *P).

se pueda devolver siguiendo sus mismos pasos. while (p >= Pila){ cout << setw(10) << *p << endl. if (Cima){ p = Cima. Para esto debe almacenar(meter). de tal suerte que en pantalla queden múltiples ventanas. arriba o abajo en una pila. la posición inicial de el agente. p--. if (Cima == P) // Era el último elemento Cima = NULL. } } void EscribirValoresEnPila(){ int *p.".cout << "\n\nSubdesbordamiento. izquierda. y así sucesivamente hasta llegar a la posición inicial. Almacene la información de cada ventana en una pila de registros para que cuando se pida desde el menú poder retirar cada una en orden inverso a como fueron creadas. else Cima--. eventualmente sobrepuestas a las anteriores. clrscr(). efectúele los cambios necesarios para que el agente que se desplaza por el mismo. } } else cout << "Pila está vacía\n". 11 . los colores déselos por defecto. y cuando se le de la orden de devolverse por medio del menú. derecha. else { cout << "\n\nSacado de la pila: " << *Cima. el ancho y el alto de la misma. A partir de un menú se debe invocar esta función. cada movimiento. Diseñe función que en modo gráfico presente una ventana al estilo de las del Windows en una posición dada por el usuario (x. 2. proceder a sacar desde el último movimiento. y) de su esquina superior izquierda. y a continuación almacenar (meter). } Programar a Manera de ejercicio 1. En el programa del laberinto que el profesor le entregará.

partamos de las definiciones de constantes y variables siguientes: const int MaxCola = 5. const int nulo = -1. por ejemplo: bancos. La palabra cola viene del poder simular con esta estructura la situación real de las colas que hay que efectuar para entrar a algún lugar o para poder recibir algún servicio. Las funciones que manejarán la cola serán: Insertar() y Atender(). Una Cola es una estructura de datos la cual almacena elementos de un tipo determinado. Debido a esto último las colas tambien son llamadas listas en las cuales el primer elemento en entrar es el primero en salir. Para las colas que trabajaremos se sobreentenderá. int final = nulo. a menos de decir lo contrario. transportes colectivos. Desarrollemos estas dos funciones de forma "simultánea". cola ┌─────┬─────┬─────┬─────┬─────┐ frente ┌─────┐ final ┌─────┐ 12 . espectáculos públicos. pasando a continuación el segundo de la cola al frente. que sigue la política de que el primer elemento que se extrae (se ‘desencola’) es el primero que se introdujo (se ‘encoló’) -primero en salir. En general en una cola. el primero que llega será atendido primero. Desde el punto de vista de las estructuras de datos una cola es una estructura de lineal. en la cual sus elementos solo pueden ser insertados por un extremo y eliminados por el otro. que la regla es que siempre el primero se atiende primero. Para la implementación de la cola utilizaremos la estructura de datos arreglo unidimensional. de la vida diaria.Cola Implementada en Arreglo Introducción : Una cola es una línea de espera como las que se forman en las casillas de los bancos o en las entradas a cine. First Out). etc. en ingles FIFO(First Input. int cola[MaxCola]. primero en entrar (FIFO)-. De aquí que el extremo por donde se insertan los elementos se llamará "final" y por donde se retiran "frente". y cada que llega un nuevo elemento este se colocará al final de la cola. Implementación . int frente = nulo.

el fragmento de código correspondiente para obtener lo anterior sería: if (frente == nulo){ //la cola estaba vacía frente = final = 0. tendríamos que colocarlo al "final de la cola". supongamos 18. así: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 15 │ 18 │ -4 │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 2 │ └─────┘ cola ┌─────┬─────┬─────┬─────┬─────┐ │ 15 │ 18 │ -4 │ 0 │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 3 │ └─────┘ cola ┌─────┬─────┬─────┬─────┬─────┐ │ 15 │ 18 │ -4 │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 4 │ └─────┘ 13 . cout << "\n\nElemento a insertar: ". cout << "\n\nElemento a insertar: ". Este será el "caso general". los cuales trataremos a continuación. lógicamente que llegará al frente. Supongamos que siguen llegando elementos a la cola. supongamos ese elemento es 15: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 15 │ │ │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 0 │ └─────┘ Las variables frente y final deben colocarse en cero. } Si llega otro elemento. quedando: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 15 │ 18 │ │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 1 │ └─────┘ Vemos que el final se ha movido hacia la derecha.│ │ │ │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 │nulo │ └─────┘ │nulo │ └─────┘ Cuando una cola está vacía el primer elemento que llegue. empero hay varios casos particulares. cin >> cola[frente]. sería: final++. el código que podría hacer esto. cin >> cola[final].

no!.Si trataramos de insertar otro más. debemos aprovechar esas posiciones. como sucedería en una cola de la vida real. cout << "\n\nElemento a insertar: ". si llega otro elemento. 1 y 2. de la siguiente forma. cin >> cola[final]. en el frente: cola ┌─────┬─────┬─────┬─────┬─────┐ │ │ 18 │ -4 │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 1 │ └─────┘ final ┌─────┐ │ 4 │ └─────┘ Observe que no vamos a correr los elementos hacia la izquierda. debería el programa darnos un mensaje de "Cola llena". Atendamos ahora al 18 en la posición frente de 1: cola ┌─────┬─────┬─────┬─────┬─────┐ │ │ │ -4 │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 2 │ └─────┘ final ┌─────┐ │ 4 │ └─────┘ Si atendemos al -4 en la posición frente igual a 2: cola ┌─────┬─────┬─────┬─────┬─────┐ │ │ │ │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 3 │ └─────┘ final ┌─────┐ │ 4 │ └─────┘ Hasta aquí podríamos copiar el algoritmo de atender(eliminar) así: cout << "Atendido el frente: " << cola[frente]. todos los elementos permanecerán siempre en el mismo sitio. Están "desocupadas" en este momento las posiciones 0. para esto mejoraremos el código anterior de esta forma: if ( (final+1 == MaxCola && frente == 0) ) cout << "cola llena ". frente++. } Ahora supongamos que se comienza a atender(eliminar) elementos. insertemos el elemento 57: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 57 │ │ │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 3 │ └─────┘ final ┌─────┐ │ 0 │ final pasa de 4 a 0 └─────┘ Es de notar que la cola que el usuario tiene en mente tiene el orden: 14 . hasta que sean atendidos. else{ final++.

por ejemplo 81: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 57 │ 14 │ 81 │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 3 │ └─────┘ final ┌─────┐ │ 2 │ └─────┘ La cola para el usuario estaría como: 0. Llegados a este punto no podríamos seguir insertando elementos. cout << "\n\nElemento a insertar: ". también llena: if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) ) cout << "cola llena ". cin >> cola[final]. el caso inicial. else if (frente == nulo){ //la cola estaba vacía frente = final = 0. ya que esta la cola está llena. 65. la cola está.0 65 57 Esto ocasiona una nueva modificación al algoritmo de insertar. else { final++. permitiendo insertar otro y de esta forma borrando el valor que tenemos en el frente. if (final == MaxCola) final = 0. else { final++. 65. 14. 15 . } } Verifique el algoritmo anterior insertando el elemento 14: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 57 │ 14 │ │ 0 │ 65 │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 3 │ └─────┘ final ┌─────┐ │ 1 │ └─────┘ La cola para el usuario estaría en este orden: 0. } A continuación insertémosle al anterior código. por ello recodificamos. 57. cout << "\n\nElemento a insertar: ". cin >> cola[final]. veamos: if ( (final+1 == MaxCola && frente == 0) cout << "cola llena ". if (final == MaxCola) // se da "la vuelta al inicio" final = 0. 81. 57. Verifique nuestro algoritmo y se dará cuenta que fracasará. 14. cout << "\n\nElemento a insertar: ". teniendo en cuenta que si el final está una posición menos que el frente. Insertemos ahora otro elemento. cuando la cola estaba vacía y tendríamos finalmente: if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) ) cout << "cola llena ".

atendiendo los demás verificándolo cada vez en el algoritmo anterior: elementos cola ┌─────┬─────┬─────┬─────┬─────┐ │ │ 14 │ 81 │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 1 │ └─────┘ final ┌─────┐ │ 2 │ └─────┘ cola ┌─────┬─────┬─────┬─────┬─────┐ │ │ │ 81 │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 2 │ └─────┘ final ┌─────┐ │ 2 │ └─────┘ en cola y Observe que cuando queda un solo elemento en cola. Eliminemos el frente. 57. sucesivamente. if (final == MaxCola) // se da "la vuelta al inicio" final = 0. posición 3. } Dediquémonos ahora a terminar la función de Atender(eliminar). Recordemos el código hasta el momento y que nos sirve para este caso: cout << "Atendido el frente: " << cola[frente]. frente++. 14. el frente es igual al final.cin >> cola[frente]. cout << "\n\nElemento a insertar: ". frente++. 81. Sigamos. Luego al eliminar el último elemento el algoritmo fallaría. el algoritmo se modifica así: cout << "\nAtendido: " << cola[frente]. Atendamos otro. las variables deberían quedar: cola frente final ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │nulo │ │nulo │ └─────┴─────┴─────┴─────┴─────┘ └─────┘ └─────┘ 0 1 2 3 4 Para esto se debe modificar nuevamente el código para Atender: 16 . if (frente == MaxCola) frente = 0. La cola para el usuario está así: 65. cin >> cola[final]. } else { // caso general final++. el 65 en posición frente de 4: cola ┌─────┬─────┬─────┬─────┬─────┐ │ 57 │ 14 │ 81 │ │ │ └─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 frente ┌─────┐ │ 0 │ └─────┘ final ┌─────┐ │ 2 │ └─────┘ El frente "da la vuelta".

.h> const int MaxCola = 5. cout << "\n\nElemento a insertar: ". si tratáramos de Atender un elemento. recodificamos el algoritmo Atender: if (frente == nulo) cout << "\nCola vacia\a". .. al fin. el algoritmo anterior nos mostraría "basura".. if (frente == MaxCola) frente = 0.exe.. const int nulo = -1.. else { cout << "\nAtendido: " << cola[frente].h> #include <conio. if (frente == MaxCola) frente = 0.. de la estructura cola en un arreglo unidimensional: //ColaVector.... void Insertar(){ if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) ){ cout << "cola llena "...cout << "\nAtendido: " << cola[frente]. int cola[MaxCola]. else{ frente++. Como resumen de lo anterior a continuación se presenta el programa COLA.. int final = nulo. int frente = nulo.CPP #include <iostream.. getch()....... } else { // caso general 17 . } } Programa Cola... } En este momento tenemos la cola vacía..h> #include <iomanip. if (frente == final) frente = final = nulo... por esto.CPP con la implementación.. } else if (frente == nulo){ //la cola estaba vacía frente = final = 0.... else{ frente++. completa... cin >> cola[frente]... if (frente == final) frente = final = nulo.

final++;
if (final == MaxCola) // se da "la vuelta al inicio"
final = 0;
cout << "\n\nElemento a insertar: ";
cin >> cola[final];
}
}
void Atender(){
if (frente == nulo)
cout << "\nCola vacia\a";
else {
cout << "\nAtendido: " << cola[frente];
if (frente == final) // cola quedó vacía
frente = final = nulo;
else{
frente++;
if (frente == MaxCola)
frente = 0;
}
}
}
void Listar(){
int i;
if (frente==nulo)
cout << "\nCola vacia \a\n";
else
if (frente <= final)
for (i=frente; i <= final; i++)
cout << setw(4) << cola[i];
else {
for (i=frente; i < MaxCola; i++)
cout << setw(4) << cola[i];
for (i=0; i <= final; i++)
cout << setw(4) << cola[i];
}
}
void main(){
char opcion;
do{
clrscr();
Listar();
cout << "\n\nInsertar Atender Salir \n";
switch (opcion=getch()){
case 'I':; case 'i': Insertar(); break;
case 'A':; case 'a': Atender(); break;
}
} while (opcion != 'S' && opcion != 's');
}
Estudie el siguiente programa, el cual tiene un pequeño cambio, en relación al
anterior:

18

Cola de Registros:
#include
#include
#include
#include

<iostream.h>
<iomanip.h>
<conio.h>
<stdio.h>

const int MaxCola = 40;
const int nulo = -1;
int frente = nulo, final = nulo;
typedef struct persona PERSONA;
struct persona{
char nombre[25];
int edad;
float alto;
} Cola[MaxCola];
void Insertar(){
PERSONA registro;
if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) ){
cout << "Cola llena ";
getch();
}
else{
cout << "\n\nDigite nombre: ";
cin >> registro.nombre;
cout << "Digite edad en años: ";
cin >> registro.edad;
cout << "Digite estatura en metros: ";
cin >> registro.alto;
if (frente == nulo){ //la Cola estaba vacía
frente = final = 0;
Cola[frente] = registro;
}
else { // caso general
final++;
if (final == MaxCola) // se da "la vuelta al inicio"
final = 0;
Cola[final] = registro;
}
}
}
void Atender(){
if (frente == nulo)
cout << "\nCola vacia\a";
else {
cout << "\nAtendido: " << Cola[frente].nombre
<< Cola[frente].edad
<< " "

<< "

"

19

<< Cola[frente].alto;
if (frente == final) // cola quedó vacía
frente = final = nulo;
else {
frente++;
if (frente == MaxCola)
frente = 0;
}
}
getch();
}
void listar(){
int i;
clrscr();
if (frente==nulo)
cout << "Cola vacia \a\n";
else
if (frente <= final)
for (i = frente; i <= final; i++)
cout
<< "\n" << Cola[i].nombre << " "
<< Cola[i].edad
<< " "
<< Cola[i].alto;
else {
for (i=frente; i<MaxCola; i++)
cout << "\n" << Cola[i].nombre << " "
<< Cola[i].edad << " " << Cola[i].alto;
for (i=0; i <= final; i++)
cout << "\n" << Cola[i].nombre << " " << Cola[i].edad
<< " " << Cola[i].alto << endl;
}
}
void main(){
char opcion;
do {
listar(); cout << "\n\nInsertar Atender
opcion = getch();
switch (opcion){
case 'I':;
case 'i': Insertar(); break;
case 'A':;
case 'a': Atender(); break;
}
} while (opcion != 'S' && opcion != 's');

Salir ";

}

Ejemplo Real de Aplicación de las Colas.............
Cola de instrucciones en microprocesadores. Algunos microprocesadores
utilizan colas como líneas de espera para sus instrucciones. Dicho de otra
manera, las instrucciones que han de ejecutarse llegan al procesador antes
de lo necesario y esperan en una cola de instrucciones. Este sistema posee
la ventaja de que cada instrucción puede extraerse de memoria mientras
otras se están ejecutando, reduciéndose en consecuencia el tiempo de
proceso. Por ejemplo, las instrucciones que incluyen directamente al dato

20

–datos inmediatos- se ejecutan prácticamente a la misma velocidad que
aquellas otras que utilizan datos de los registros de la CPU. Es también
muy útil cuando se usa el procesador con memorias lentas tales como
EPROM(Erasable Read Only Memory)
La situación es muy similar a la de un jefe que tiene una secretaria para
coger el teléfono y para la correspondencia. La secretaria trabaja al mismo
tiempo que el jefe hace otras cosas, liberándole de muchos detalles del mundo
exterior. Las llamadas que se acumulan para el jefe se tratan se una en una, y
en el orden que prefiera el jefe.

Programa a Realizar como Ejercicio..................
Suponga que 4 estudiantes se dirigen en cola a la biblioteca, cada uno de ellos
lleva en su maletín escolar un número diferente de libros (suponga un máximo de
10 libros), los cuales deben dejar en la portería. Para esto, colocan los libros
formando pilas separadas para cada uno en una mesa, cada una a continuación de la
otra, formando una cola de pilas de libros. Después de unas horas los estudiantes
se retiran formando una cola en el mismo orden que al entrar, retirando cada uno
de ellos sus libros y colocando cada uno de ellos en su maletín escolar.
Simule el proceso anterior por medio de la elaboración de un programa en
lenguaje C++. Debe considerar el nombre de cada uno de los estudiantes y su
número de libros en la cola, y así mismo el nombre de cada uno de los libros en
las pilas.
La abstracción de la estructura de datos a realizar es la siguiente:
- Las pilas de libros represéntelas en cuatro vectores separados, de 10
posiciones cada uno.
- La cola de estudiantes represéntela como dos vectores paralelos de cuatro
sendas posiciones así: uno para los nombres de cada estudiante y el otro para
manejar la cima de la pila de libros de cada uno de los estudiantes.
PILAS DE LIBROS EN COLA
┌─────────┐
└──┬─────┬┘
┌──┴─────┴──┐
└─┬─────────┤
┌┴────────┬┘
└─────────┘

┌─────────┐
└───┬─────┴──┐
┌──┴────────┤
└┬────────┬─┘
└────────┘

┌─────────┐
┌───────┐
└───┬─────┴──┐
├───────┴┐
┌──┴────────┤
┌┴────────┴┐ └┬─────────┬┘
└──────────┘
└─────────┘

VECTOR CIMAS
┌────────────────┬─────────────────┬───────────────┬──────────────┐

5

4

3

4

└────────────────┴─────────────────┴───────────────┴──────────────┘
0
1
2
3
VECTOR NOMBRES
┌────────────────┬─────────────────┬───────────────┬──────────────┐

nombre_1

nombre_2

nombre_3

nombre_4

└────────────────┴─────────────────┴───────────────┴──────────────┘
0
1
2
3

21

Insertar().. if (final == MaxCola) final = 0.. else{ frente++... } El siguiente dibujo es la representación en RAM inicial: cola frente final ┌─────┬─────┬─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │-1 │ │-1 │ recuerde que Vacia=-1 └─────┴─────┴─────┘ └─────┘ └─────┘ 0 1 2 22 . Insertar(). const int MaxCola = 3. Vacia = -1. cout << "\n\nElemento a insertar: ". cout << "\n\nElemento a insertar: ". cola[MaxCola]... Insertar(). if (frente == final) frente = final = Vacia. .. .... Insertar(). else if (frente == Vacia){ frente = final = 0. else { cout << "\nAtendido: " << cola[frente]. if (frente == MaxCola) frente = 0.. cin >> cola[final]. } } } void main(){ Atender(). } else { // caso general final++. Insertar(). Atender().. final = Vacia.. } } void Atender(){ if (frente == Vacia) cout << "\nCola vacia\a".. //variables globales void Insertar(){ if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) ) cout << "cola llena ". int frente = Vacia. Atender().Efectúe Prueba de Escritorio. Atender(). .. Insertar(). cin >> cola[frente]..

23 .

esto es lo que se conoce como el criterio base de la función recursiva. es decir que en el ámbito de ella se efectúa una llamada con el mismo identificador con el que está definida.. Explicaremos el mecanismo de invocaciones cálculo del factorial de un número.. el compilador le asigna una dirección base de memoria a partir de la cual "trabajará" esta función. hasta llegar al resultado deseado: Fac(1) = 1 * Fac(0) = 1 * 1 = 1 Fac(2) = 2 * Fac(1) = 2 * 1 = 2 Fac(3) = 3 * Fac(2) = 3 * 2 = 6 Fac(4) = 4 * Fac(3) = 4 * 6 = 24 Fac(5) = 5 * Fac(4) = 5 * 24 = 120 A partir de esto codificaremos la siguiente función recursiva: float factorial(int n){ float fac. toda función recursiva debe estar construida de tal suerte que bajo alguna condición no se siga invocando más. por esto en cada nueva invocación recursiva. 24 . * N Factorial(N) = N * Factorial(N-1) Veamos el siguiente ejemplo: Fac(5) = 5 * Fac(5-1) = 5 * Fac(4) Fac(4) = 4 * Fac(4-1) = 4 * Fac(3) Fac(3) = 3 * Fac(3-1) = 3 * Fac(2) Fac(2) = 2 * Fac(2-1) = 2 * Fac(1) Fac(1) = 1 * Fac(1-1) = 1 * Fac(0) Fac(0) = 1 sabemos que factorial de cero es igual a uno. En cada invocación de una función. tomaremos este hecho como el "criterio base" y a partir de aquí nos "devolvemos" reemplazando en las expresiones anteriormente obtenidas. INTRODUCCIÓN La recursión consiste en la invocación de una función a si misma. el compilador asignará nuevas direcciones de memoria. de esta forma y eventualmente la memoria podría llegar a llenarse. recursivas con el ejemplo De la definición del factorial de un número: Factorial(N) = 1 * 2 debería usted estar de acuerdo con lo siguiente: del .RECURSIÓN 1. if (n == 0) return (1). En cada invocación se harían copias de los parámetros que se estén pasando y de las variables locales en ella definidas.. Para evitar el llenar la memoria del computador.

El algoritmo continuará en │ ┌────┐ │ │ │ │ │ fac = n * factorial(n-1). │ │ = 3 * factorial(2). } Supongamos que al efectuar su invocación inicial. │ └────┘ │ = 3 * factorial(3-1). tercera para la función. en memoria se gestionará un nuevo "espacio" así: factorial(3) ┌─────────┐ │ n │ │ ┌────┐ │ entra a la función recibiendo n el valor de 3 │ │ 3 │ │ n y fac son "otras" variables locales │ └────┘ │ │ fac │ if (n==0) es falso. ver el programa RECURSI. representemos ese espacio como un rectángulo y de esta forma tener una mejor abstracción de lo que ocurre. se invoca recursivamente └─────────┘ Con el valor de n=4 se produce una invocación recursiva de la función. se le está pasando por valor el entero 5: el compilador le asignará a la función un "espacio" en la memoria para realizar su trabajo. se invoca recursivamente └─────────┘ 25 . │ └────┘ │ = 4 * factorial(4-1). return(fac). │ │ = 5 * factorial(4). gestiona una nueva dirección en memoria para trabajar en esta nueva invocación. │ └────┘ │ = 5 * factorial(5-1). que el compilador y a través del sistema operativo.CPP siguiente.fac = n * factorial(n-1). el algoritmo continuará en │ ┌────┐ │ │ │ │ │ fac = n * factorial(n-1). │ │ = 4 * factorial(3). se invoca recursivamente └─────────┘ Con el valor de n=3 se produce una segunda invocación recursiva. así: factorial(5) ┌─────────┐ │ n │ │ ┌────┐ │ entra a la función recibiendo n el valor de 5 │ │ 5 │ │ se define la variable local fac │ └────┘ │ │ fac │ if (n==0) es falso. debemos imaginarnos y es realmente lo que ocurre. así: factorial(4) ┌─────────┐ │ n │ │ ┌────┐ │ entra a la función recibiendo n el valor de 4 │ │ 4 │ │ se define otra variable local fac │ └────┘ │ │ fac │ if (n==0) será falso. El algoritmo continuará en │ ┌────┐ │ │ │ │ │ fac = n * factorial(n-1).

se invoca recursivamente └─────────┘ Se producirá una nueva invocación pasando el valor de cero. la función se ha invocada cuatro veces. en la última con el valor de n=2 en memoria se gestionará un nuevo "espacio" así: factorial(2) ┌─────────┐ │ n │ │ ┌────┐ │ se crea una nueva variable n recibiendo un valor de 2 │ │ 2 │ │ fac será otra variable local │ └────┘ │ │ fac │ if (n==0) es falso.Hasta el momento. y vuelve DONDE FUE │ │ INVOCADA └─────────┘ 26 . │ └────┘ │ = 2 * factorial(2-1). se sale. │ │ │ │ │ └────┘ │ la función termina. debe tenerse en mente. así: factorial(0) ┌─────────┐ │ n │ │ ┌────┐ │ se crea una nueva variable n recibiendo un valor de 0 │ │ 0 │ │ fac será otra variable local │ └────┘ │ │ fac │ if (n==0) es verdadero │ ┌────┐ │ return (1). se invoca recursivamente └─────────┘ La siguiente invocación nos la imaginaremos así: factorial(1) ┌─────────┐ │ n │ │ ┌────┐ │ se crea una nueva variable n recibiendo un valor de 1 │ │ 1 │ │ fac será otra variable local │ └────┘ │ │ fac │ if (n==0) es falso. el algoritmo continuará en │ ┌────┐ │ │ │ │ │ fac = n * factorial(n-1). │ │ = 2 * factorial(1). │ └────┘ │ = 1 * factorial(1-1). tres de las cuales son recursivas. el algoritmo continuará en │ ┌────┐ │ │ │ │ │ fac = n * factorial(n-1). │ │ = 2 * factorial(0).

27 .La función alcanza el criterio base. es decir en(devuelva la página para comparar): factorial(1) ┌─────────┐ │ n │ │ ┌────┐ │ │ │ 1 │ │ │ └────┘ │ │ fac │ │ ┌────┐ │ │ │ 1 │ │ │ └────┘ │ │ │ └─────────┘ fac = n * factorial(n-1). y el programa sigue en la invocación anterior a esta. retornando este valor a la anterior invocación. = 2 * factorial(1). = 1 * factorial(1-1). de la siguiente forma: factorial(3) ┌─────────┐ │ n │ │ ┌────┐ │ │ │ 3 │ │ │ └────┘ │ │ fac │ │ ┌────┐ │ │ │ 6 │ │ │ └────┘ │ │ │ └─────────┘ fac = n * factorial(n-1). de esta forma se ejecuta la instrucción return(1). = 3 * factorial(3-1). el 1 retornado "llega" a factorial(0) y de este modo se sigue: fac = 1 * factorial(0) = 1*1 = 1 continuando en return(fac) return(2) y termina esta invocación Vemos que la invocación de factorial(0) recibe el valor de 1 y se produce la evaluación de la expresión que calcula el valor para fac de 1. el 1 retornado "llega" a factorial(1) y de este modo se sigue: fac = 2 * factorial(1) = 2*1 = 2 continuando en return(fac) return(2) y termina esta invocación Vemos que la invocación de factorial(1) recibe el valor de 1 y se produce la evaluación de la expresión que calcula el valor para factorial de 2 de 1. la función termina retornando un 1. se borra de la memoria. = 1 * factorial(0). de la siguiente forma: factorial(2) ┌─────────┐ │ n │ │ ┌────┐ │ │ │ 2 │ │ │ └────┘ │ │ fac │ │ ┌────┐ │ │ │ 2 │ │ │ └────┘ │ │ │ └─────────┘ fac = n * factorial(n-1). cuando n=0. el 2 retornado "llega" a factorial(2) y de este modo se sigue: fac = 3 * factorial(2) = 3*2 = 6 continuando en return(fac) return(6) y termina esta invocación de nuevo en la invocación que corresponde a factorial(4) tenemos: factorial(4) ┌─────────┐ │ n │ fac = n * factorial(n-1). retornando este valor a la anterior invocación. = 2 * factorial(2-1). = 3 * factorial(2).

el 6 retornado "llega" a factorial(3) y de este modo se sigue: fac = 4 * factorial(3) = 4*6 = 24 continuando en return(fac) return(24) y termina esta invocación Estamos ahora en la invocación inicial de factorial(5): factorial(5) ┌─────────┐ │ n │ │ ┌────┐ │ │ │ 5 │ │ │ └────┘ │ │ fac │ │ ┌────┐ │ │ │ 120│ │ │ └────┘ │ │ │ └─────────┘ fac = n * factorial(n-1). = 5 * factorial(4). = 4 * factorial(3).│ ┌────┐ │ │ │ 4 │ │ │ └────┘ │ │ fac │ │ ┌────┐ │ │ │ 24 │ │ │ └────┘ │ │ │ └─────────┘ = 4 * factorial(4-1). el 24 retornado "llega" a factorial(4) y de este modo se sigue: fac = 5 * factorial(4) = 5*24 =120 continuando en return(fac) return(120) y termina esta invocación Regresamos de esta forma al sitio donde se invocó originalmente la función con el valor de 120 retornado. Resumiendo el proceso de invocaciones y el "espacio que ocupó" en memoria fue el siguiente: 28 . = 5 * factorial(5-1). y terminado todo el proceso de invocaciones.

1. } 3. } float factorial(int n){ if (n == 0) return (1).h> long int MCD(int a.CPP #include <ConStrea. int b){ if ( !b ) return a. Escribir << setbk(MAGENTA) << setclr(GREEN) << setxy(10. cin >> n. cout << "Digite un número negativo para terminar\n\n". Ejemplo de función recursiva. Escribir << setbk(CYAN) << setclr(RED) << setxy(10. } void main(){ long int a. cin >> b.7) << "Digite otro entero: ".5) << "Digite entero: ".9) << "Máximo común divisor = " << MCD(a.window(1.h> #include <conio. else return ( MCD(b. textbackground(BLUE). Cálculo de un factorial. void main(){ int n. a%b) ). Escribir << setbk(BROWN) << setclr(GREEN) << setxy(10. Escribir. if (n >= 0) cout <<"factorial = " << factorial(n) << endl.80.CPP float factorial(int n). //MCD. cin >> a. Escribir.clrscr().h> //RECURSI1.2. b). } 29 . constream Escribir. return ( n * factorial(n-1) ). clrscr(). #include <iostream. do{ cout << "Número entero: ". }while (n >= 0). b.25). Calculo del máximo común divisor de dos números enteros.

if ((n == 1) || (n == 0)) return(1). } getch().width(6). cout << coeficiente. cout. coeficiente. espacio. espacio <= (80/2-6)-n*3. for(i = 0.4. clrscr(). for(n = 0. espacio++) cout << " ". cout << "\t\tTRIANGULO DE PASCAL DE COEFICIENTES BINOMIALES\n\n". } Tabla: Triángulo de Pascal de coeficientes binomiales. return(f).h> //RTPASCAL. } cout << endl.h> #include <conio. i. f = n * factorial(n-1). i++){ coeficiente = factorial(n)/(factorial(i)*factorial(n-i)). i <= n. n <= N. n++) { for(espacio=1. main(){ int N=10. 1 1 1 1 1 1 5 1 3 6 10 1 4 10 1 1 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 9 36 84 126 126 84 36 9 10 45 120 210 252 210 120 45 1 1 3 4 1 1 2 5 6 1 1 10 1 30 .CPP float factorial(int). } float factorial(int n){ float f. n. Triángulo de Pascal de coeficientes binomiales n n-i i S ( n! / (i!×(n-i)!))×a × b i=0 (a+b)_ = #include <iostream.

5 Multiplicar dos números utilizando recursión. Sin operador *.
#include <iostream.h>
#include <conio.h>
//RECURSI2.CPP
float multiplicar(float a, int b){
if (b==1)
return (a);
return(multiplicar(a,b-1) + a);
}
void main(){
float a=2;
int b=4;
clrscr();
cout << a << " * " <<
getch();

b << " = " << multiplicar(a,b);

}
Veamos una prueba para el anterior algoritmo:
Multiplicar(2,4)= Multiplicar(2,4-1)+ 2 = Multiplicar(2,3) + 2
Multiplicar(2,3)= Multiplicar(2,3-1)+ 2 = Multiplicar(2,2) + 2
Multiplicar(2,2)= Multiplicar(2,2-1)+ 2 = Multiplicar(2,1) + 2
Multiplicar(2,1) = 2
Multiplicar(2,2)= Multiplicar(2,1) + 2 = 2 + 2 = 4
Multiplicar(2,3)= Multiplicar(2,2) + 2 = 4 + 2 = 6
Multiplicar(2,4)= Multiplicar(2,3) + 2 = 6 + 2 = 8
6. Eleve el número 10 a diferentes potencias utilizando una función recursiva.
//RECURS_3.CPP
#include <IOSTREAM.H>
#include <CONIO.H>
float potencia (int, int);
main(){
int x = 10;
int y = 0;
clrscr();
do{
cout << "\n10 elevado a la " << y << " = " << potencia(x, y);
y++;
}while ( y<11 );
}
float potencia (int base, int exponente){
if ( exponente < 0 )
return(-1);
else
if (exponente == 0)
return(1); /* criterio base */
else
return (base * potencia (base, exponente-1));
}

31

7. Se pasa un número de base 10 a base 2 utilizando recursión.
#include <iostream.h>
#include <conio.h>
//RDECIBIN.CPP
void DecimalABinario(int Dividendo){
int cociente, resto;
cociente = Dividendo >> 1; //Divide entre dos, desplaza un byte a derecha
resto = Dividendo % 2;
if(cociente)
DecimalABinario(cociente);
cout << resto;
}

void main(){
int dec;
clrscr();
cout << "Digite un entero: ";
cin >> dec;
cout << "\nEn binario es = ";
DecimalABinario(dec);
}
8. Presenta las tablas de multiplicar desde un valor t1 a uno t2. Utilizando
recursión. Efectúe prueba de ejecución manual. Explique en palabras lo que hace;
muestre lo más gráficamente que pueda cada una de las invocaciones recursivas;
mencione los criterios base para cada una de las funciones, escriba como se
"devuelven" las invocaciones recursivas; de los correspondientes valores a las
variables en cada invocación.
#include <conio.h>
#include <dos.h>
#include <iostream.h>
//R_TABLAM.CPP
void Tabla(int a, int b){
if(b>1)
Tabla(a, b-1);
cout << a << " x " << b << " = " << a*b << endl;
}
void Tablas(int del, int al){
if(del < al)
Tablas(del, al-1);
clrscr();
Tabla(al,10);
delay(500);
}
void main(){
int t1,t2;
clrscr();
cout << "Número de la tabla inicial: ";

32

cin >> t1;
cout << "Número de la tabla final: ";
cin >> t2;
Tablas(t1,t2);
}
Efectúe a continuación prueba de ejecución manual del algoritmo del anterior
programa. Llene el siguiente tabulado y "pantalla".
Variables en forma tabular
"PANTALLA"
t1

t2

del

al

a

b

33

9. Serie de Fibonacci utilizando recursión:
Serie:
0 1 1 2 3 5 8 13 21 34
Posición:
0 1 2 3 4 5 6
7
8
9

55
10

89
11
//RFIBONAC.CPP

#include <iostream.h>
#include <conio.h>
int fibonacci(int n){
if (n <= 1)
return (n);
return(fibonacci(n-2) + fibonacci(n-1));
}
main(){
int N=11;
clrscr();
cout <<"El " <<N <<" término de la serie de Fibonacci es " << fibonacci(N);
getch(); return 0;
}

10. La función Log2, la cual encuentra el logaritmo en base 2 de n, se puede
definir en forma recursiva de la siquiente forma:
Log2(n) = 0

si n = 1

Log2(n) = 1 + Log2( [n/2] )

si n > 1
RLOG2_N.CPP

#include <iostream.h>
#include <conio.h>
int Log2(int n){
if (n < 1)
return -1;
if (n == 1)
return 0;
return ( 1 + Log2(n/2) ) ;
}
void main(){
int N, L;
clrscr(); cout << "Digite un Entero: ";
cin >> N;
L = Log2(N);
if ( L<0 )
cout << "Error \a";
else
cout << "Parte entera del Logaritmo en base 2 de " << N << " = " << L;
}

34

5).h> //RMULTIPL. } 12.8 * 5 = " << multiplicar(12. clrscr().B) = MCD(B.CPP int MCD(int A. getch(). Sin operador *. return (multiplicar(a. } void main(){ clrscr(). Implementación del Algoritmo de Euclides para el cálculo del Máximo Común Divisor: Sean A y B enteros no negativos. cout << "Máximo Común Divisor de " << a << " y " << b << " es " << MCD(a. A%B)). int b){ if(b==1) return a.11.h> #include <conio. getch().b). else if (!B) return A. b = 130. A % B) si A < B si B = 0 de otro modo #include <iostream. Multiplicar dos números utilizando recursión. } void main(){ int a = 13.CPP float multiplicar(float a.h> //REUCLIDES. #include <iostream. Suponga que una función MCD se define recursivamente como sigue: MCD(A.B) = A MCD(A. else return(MCD(B.h> #include <conio. b-1) +a). } 35 .B) = MCD(B. int B){ if (A<B) return(MCD(B.A)). cout << "12.8.A) MCD(A.

der) ).121}.CPP int Ackermann(int m. for(i=0. cout << "Digite un entero pequeño(0 al 3): ".65. else if (item > v[medio]) return( BusquedaBinaria(medio+1. #include <iostream.8.b) . if (item < v[medio]) return( BusquedaBinaria(izq. cout << "Digite otro entero pequeño: ". //Observe Vector ordenado int BusquedaBinaria(int izq. // Criterio Base } else return -1.4. i<Max. } void main(){ int a. Algoritmo de búsqueda binaria.CPP const int Max = 10.73. cout << "\nACKERMANN(" << a << ".13. } cout << endl.99.87. cin >> a. i<Max. cout << "FUNCION RECURSIVA DE ACKERMANN\n\n".1) ). else return medio.12.h> //RACKERMAN. 36 . for(i=0. Debe hacerse sobre un vector ordenado.h> //RBBINARIA. i++){ cout. clrscr(). else if ((m != 0) && (n==0)) return( Ackermann(m-1.h> #include <conio. Min = 0. int n){ if (m == 0) return(n+1). medio-1) ).h> #include <conio. cout << v[i]. b. Ackermann(m. v[Max]={2.width(5). cin >> b. } 15. #include <iostream." << b << ") = " << Ackermann(a. int item. Se utiliza recursión.14. Cálculo de la función recursiva de Ackermann.width(5). i++){ cout. cout << i. // No se encuentra } void main(){ int i. n-1) ) ). if (izq <= der){ medio = (izq + der) >> 1. int der){ int medio. else return( Ackermann( m-1.

inicio. aux. TORRES DE HANOI: El objeto de este juego es mover de un poste inicial N discos de diferente tamaño.} cout << "\n\nDigite número a buscar en el vector: ". } void torres(int N. Max-1). de poste a poste.//N-1 discos del poste auxiliar al final } } Para 3 anillos:        Mover Mover Mover Mover Mover Mover Mover Torre Torre Torre Torre Torre Torre Torre Para 4 anillos: 1 1 3 1 2 2 1 a a a a a a a Torre Torre Torre Torre Torre Torre Torre 3 2 2 3 1 3 3 Mover Torre 1 a Torre 2  Mover Torre 1 a Torre 3  Mover Torre 2 a Torre 3  Mover Torre 1 a Torre 2  Mover Torre 3 a Torre 1  Mover Torre 3 a Torre 2  Mover Torre 1 a Torre 2  Mover Torre 1 a Torre 3  Mover Torre 2 a Torre 3  Mover Torre 2 a Torre 1  Mover Torre 3 a Torre 1  Mover Torre 2 a Torre 3  Mover Torre 1 a Torre 2  Mover Torre 1 a Torre 3  Mover Torre 2 a Torre 3 37 . poste1. clrscr(). //TORHANOI.h> void torres(int N. poste3). else{ torres(N-1. int final).final. cin >> item. torres(anillos.CPP #include <iostream. else cout << "\n\n" << item << " no se encuentra". int inicio. colocados de mayor a menor tamaño uno encima de otro. int final){ if (N == 1) cout << "Mover torre " << inicio << " a torre " << final << endl. final). Solo se puede mover un disco cada vez. void main(){ int anillos=0. int inicio. } 16. Nunca puede haber un disco mayor sobre un disco menor. i = BusquedaBinaria(Min. aux). poste3=3.//N-1 discos del poste inicial al auxiliar cout << "Mover torre " << inicio << " a torre " << final << endl. inicio. poste2=2. int aux. hasta un poste final y utilizando un poste auxiliar. cout << "Número de anillos con que quiere jugar: ". if ( (i>=Min) && (i<Max) ) cout << "\n\n" << v[i] << " está en la posición " << i. const int poste1=1.h> #include <conio. torres(N-1. poste2. cin >> anillos. int aux.

PROGRAMA A REALIZAR COMO EJERCICIO Realice programa tipo tutor(para sus compañeros del próximo semestre). sin espíritu de represión. 38 . el profesor deberá estar contento de ver sus avances y tratará de corregir sus eventuales errores(siempre cometeremos errores). de modo que comente en cada clase con el profesor sus avances y dudas. en modo gráfico. el cumplimiento del objetivo en sí no es lo importante(recuerde que el fin no debe justificar los medios). y el cual permita explicar uno cualquiera de los algoritmos del presente capítulo sobre recursividad. Recuerde que en el modelo constructivo de educación lo importante es el proceso que se lleve a cabo para llegar al objetivo.

con el número en posición der=11. nuevamente estan en posiciones relativas adecuadas a nuestro ordenamiento ascendente. Se verifica que 43 y 50 están en posiciones relativas. posición 12 cuyo valor es 50. se procederá entonces a su intercambio. adecuadas. por esto se decrementa derecha (Der--): ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 0 │10 │ 43│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 21│ 45│ 50│ 0 │ 43 │ └───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴──────┴──────┘ Pivote <────┘ Se compara ahora 43 con 21 de la posición der=10. 43. es decir 45. para ello partamos del siguiente vector: Quicksort o de ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 0 │12 │ 43│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 21│ 45│ 50│ 0 │ 43 │ └───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴─┬─┴──────┴──────┘ Pivote <────┘ En este caso la posicíon más a la izquierda es 0. así: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 0 │11 │ 43│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 21│ 45│ 50│ 0 │ 43 │ └───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴──────┴──────┘ Pivote <────┘ Se compara ahora el pivote 43.ALGORITMO DEL QUICKSORT A continuación se explica una versión del algoritmo del clasificación rápida. quedando el vector. por esto comenzamos a movernos a la izquierda. paso a paso así: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 0 │10 │ 21│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 21│ 45│ 50│ 0 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 43│ 45│ 50│ 10 │ │ └───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴──────┴──────┘ 39 . ascendentemente. tal como está escrito en la tabla anterior. decrementando der. con el valor más a la derecha. en posición cero. no están en posiciones relativas ordenadas. se escoge como "pivote" el primer término de la lista. la más a la derecha es 12. Se procede a comparar el pivote. es decir la posición más a la izquierda.

Así se compara 43 con 21. los cuales estan en posiciones relativas adecuadas: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 1 │10 │ 21│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 43│ 45│ 50│ 10 │ 43 │ └───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴──────┴──────┘ └────> Pivote por esto se incrementa izquierda y se compara el 43 con el 2. ahora está en 10. se incrementa izquierda nuevamente llegando a donde está el número 90 en la posición 2 del vector: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 2 │10 │ 21│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 43│ 45│ 50│ 10 │ 43 │ └───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴──────┴──────┘ └────> Pivote El 90 al compararlo con el pivote 43 es mayor. y se comienza a comparar desde la izquierda.└────> Pivote Se actualiza la posición del pivote. igualmente están en orden ascendente relativo. y actualizada la posición del pivote: por esto deberán ser ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 2 │10 │ 21│ 2 │ 90│ 50│ 87│100│-10│ 68│ 13│ 7 │ 90│ 45│ 50│ 10 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 43│ 50│ 87│100│-10│ 68│ 13│ 7 │ 90│ 45│ 50│ 2 │ │ └───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴──────┴──────┘ Pivote <────┘ Siguiendo este proceso se obtiene la siguiente secuencia de posiciones: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 2 │ 9 │ 21│ 2 │ 43│ 50│ 87│100│-10│ 68│ 13│ 7 │ 90│ 45│ 50│ 2 │ 43 │ └───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴──────┴──────┘ Pivote <────┘ ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 2 │ 9 │ 21│ 2 │ 7 │ 50│ 87│100│-10│ 68│ 13│ 7 │ 90│ 45│ 50│ 2 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 50│ 87│100│-10│ 68│ 13│ 43│ 90│ 45│ 50│ 9 │ │ └───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴──────┴──────┘ └────> Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ 40 . como lo señala la flecha en la tabla anterior. intercambiados.

│izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 3 │ 9 │ 21│ 2 │ 7 │ 50│ 87│100│-10│ 68│ 13│ 43│ 90│ 45│ 50│ 9 │ 43 │ └───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴──────┴──────┘ └────> Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 3 │ 9 │ 21│ 2 │ 7 │ 50│ 87│100│-10│ 68│ 13│ 50│ 90│ 45│ 50│ 9 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 43│ 87│100│-10│ 68│ 13│ 50│ 90│ 45│ 50│ 3 │ │ └───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴──────┴──────┘ Pivote <───┘ ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 3 │ 8 │ 21│ 2 │ 7 │ 43│ 87│100│-10│ 68│ 13│ 50│ 90│ 45│ 50│ 3 │ 43 │ └───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴──────┴──────┘ Pivote <───┘ ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 3 │ 8 │ 21│ 2 │ 7 │ 13│ 87│100│-10│ 68│ 13│ 50│ 90│ 45│ 50│ 3 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 13│ 87│100│-10│ 68│ 43│ 50│ 90│ 45│ 50│ 8 │ │ └───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴──────┴──────┘ └────> Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 4 │ 8 │ 21│ 2 │ 7 │ 13│ 87│100│-10│ 68│ 43│ 50│ 90│ 45│ 50│ 8 │ 43 │ └───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴─┬─┴───┴───┴───┴───┴──────┴──────┘ └────> Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 4 │ 8 │ 21│ 2 │ 7 │ 13│ 87│100│-10│ 68│ 87│ 50│ 90│ 45│ 50│ 8 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 13│ 43│100│-10│ 68│ 87│ 50│ 90│ 45│ 50│ 4 │ 43 │ └───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴─┬─┴───┴───┴───┴───┴──────┴──────┘ Pivote <────┘ ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 4 │ 7 │ 21│ 2 │ 7 │ 13│ 43│100│-10│ 68│ 87│ 50│ 90│ 45│ 50│ 4 │ 43 │ └───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴─┬─┴───┴───┴───┴───┴───┴──────┴──────┘ Pivote <────┘ 41 .

QUICKPIL.┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 4 │ 6 │ 21│ 2 │ 7 │ 13│ 43│100│-10│ 68│ 87│ 50│ 90│ 45│ 50│ 4 │ 43 │ └───┴───┴───┴───┴───┴───┴─┬─┴───┴─┬─┴───┴───┴───┴───┴───┴───┴──────┴──────┘ Pivote <───┘ ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 4 │ 6 │ 21│ 2 │ 7 │ 13│-10│100│-10│ 68│ 87│ 50│ 90│ 45│ 50│ 4 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 13│-10│100│ 43│ 68│ 87│ 50│ 90│ 45│ 50│ 6 │ │ └───┴───┴───┴───┴───┴───┴─┬─┴───┴─┬─┴───┴───┴───┴───┴───┴───┴──────┴──────┘ └───> Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 5 │ 6 │ 21│ 2 │ 7 │ 13│-10│100│ 43│ 68│ 87│ 50│ 90│ 45│ 50│ 6 │ 43 │ └───┴───┴───┴───┴───┴───┴───┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──────┴──────┘ └───>Pivote ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 5 │ 6 │ 21│ 2 │ 7 │ 13│-10│100│100│ 68│ 87│ 50│ 90│ 45│ 50│ 6 │ 43 │ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ │ │ │ │ │ 21│ 2 │ 7 │ 13│-10│ 43│100│ 68│ 87│ 50│ 90│ 45│ 50│ 5 │ │ └───┴───┴───┴───┴───┴───┴───┴─┬─┴──┬┴───┴───┴───┴───┴───┴───┴──────┴──────┘ Pivote<───┘ Al avanzar desde la derecha hacia la izquierda. desde la posición 6 hasta la 12. la variable der se encuentra con la posición donde está el pivote. Ejemplo de aplicación de la estructura pila en el ordenamiento por el algoritmo del QuickSort. 43. El correspondiente programa. asi: ┌───┬───┬───────────────────────────────────────────────────┬──────┬──────┐ │izq│der│ 0 1 2 3 4 5 6 7 8 9 10 11 12 │PosPiv│Pivote│ ├───┼───┼───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┼──────┼──────┤ │ 5 │ 5 │ 21│ 2 │ 7 │ 13│-10│ 43│100│ 68│ 87│ 50│ 90│ 45│ 50│ 5 │ 43 │ └───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴──────┴──────┘ Pivote Se observa que el valor del pivote. con todos sus elementos menores.h> 42 . es decir las tres variables "se encuentran en el mismo sitio". está en el sitio que le corresponde en ordenamiento ascendente. A partir de este punto se procede con el mismo procedimiento sequido para la lista completa.CPP #include <iostream. y que a su izquierda se forma una sublista. se presenta a continuación: 2. El profesor explicará en clase magistral las reglas de juego del algoritmo. en cada una de las sublistas y por separado. usted deberá efectuar prueba de ejecución manual y entender su abstracción. e izq ya estaba en el mismo valor. desordenada.CPP. y una sublista a la derecha. en desorden y con todos mayores que el pivote. desde la posición 0 a la 4. //QUICKPIL.

cima++. mayor[cima] = N-1. mayor[cima] = PosPiv . menor[cima] = 0. PosPiv. com.h> # include <stdlib.h> const int N=100. if ( com < PosPiv . menor[N]. a[der] = pivote.#include <iomanip. return(PosPiv). } PosPiv = der. while (cima > -1) { com = menor[cima]. a[izq] = pivote. PosPiv = QuickSort(arreglo.1) { cima++. fin.1. cima--. } if (PosPiv + 1 < fin){ cima++.h> #include <conio. while ((a[izq] <= pivote) && (izq != PosPiv)) izq++. fin = mayor[cima]. if (PosPiv != izq){ if (a[izq] > pivote){ a[PosPiv] = a[izq]. com. do { while ((pivote <= a[der]) && (PosPiv != der)) der --. int QuickSort(int *a. int der){ int PosPiv=izq. pivote=a[PosPiv]. fin). mayor[N]. mayor[cima] = fin.h> #include <values. int izq. if (PosPiv != der) { if (pivote > a[der]) { a[PosPiv] = a[der]. menor[cima] = PosPiv + 1. } void Ordenar(int *arreglo){ /* Clasificación rápida */ int cima = -1. } PosPiv = izq. menor[cima] = com. } } } while ( (PosPiv != der) || (PosPiv != izq) ). } 43 .

i < N. int vector[N]. cout << setw(8) << vector[i]. cout << "\n\nOrdenados son:\n". randomize(). i < N. clrscr(). i++) { vector[i] = random(MAXINT).} } void main(){ int i. } Ordenar(vector). cout << N << " Números generados al azar:\n". i++) cout << setw(8) << vector[i]. for (i = 0. } 44 . for (i = 0.

} } while(i <= d). //Variable global void QuickSort(int izq. i++) { Vector[i] = (float) rand(). N-1).3. i < N. der). i++){ cout.width(10). medio = Vector[(izq+der)/2]. } } 45 .CPP const int N=50. randomize(). i++. while (medio < Vector[d]) d--. con el algoritmo de QuickSort.h> #include <stdlib. aux. cout. for (i = 0. do{ while (Vector[i] < medio) i++. for (i = 0. Se utiliza recursión. cout << "\n\nLos números ordenados son:\n\n". i < N. cout << Vector[i]. Vector[d] = aux. if(izq < d) QuickSort(izq.h> #include <conio. } QuickSort(0. Clasificación de un vector generado al azar. int der) /* QuickSort */ { register int i=izq. } void main(){ int i=0. if(i <= d) { aux = Vector[i]. float medio. Vector[i] = Vector[d]. cout << Vector[i]. cout << N << " Números generados al azar \n\n". d=der. clrscr(). d--. d).width(10). float Vector[N]. #include <iostream.h> //RQUICKSOR. if(i < der) QuickSort(i.

der). if(izq < d) QuickSort(izq. } } while(i <= d). Se utiliza recursión. while (strcmp(mitad.18 Clasificación de un vector de cadenas algoritmo del QuickSort. cout << "Digite " << N << " palabras\n". QuickSort(0. if(i <= d) { strcpy(aux. Cadena[d]). clrscr(). cout << "\n\tLas palabras ordenadas son:\n\n". d--. strcpy(Cadena[i]. con el #include <iostream.h> #include <conio. aux[LargoCadena]. i++) cout << Cadena[i] << endl.1. aux). //Variable global void QuickSort(int izq.h> //RQUICKCAD. const int LargoCadena=20. de caracteres(matriz). char Cadena[N][LargoCadena]. int der) /* Función recursiva QuickSort */ { register int i=izq. strcpy(Cadena[d].h> #include <string. i++. if(i < der) QuickSort(i. strcpy(mitad. i < N. while (i < N) cin >> Cadena[i++]. } 46 . N-1). Cadena[i]). } void main(){ int i=0. Cadena[d]) < 0) d--. d). char mitad[LargoCadena]. Cadena[(izq+der)/2]). for (i = 0.CPP const int N=5. do{ while (strcmp(Cadena[i]. mitad) < 0) i++. d=der.

La variable VAR se encuentra en la dirección de memoria 1000(inicia desde hay).PUNTEROS O APUNTADORES 1. 2. entero=13. empero lo supondremos de esta forma por facilidad. *. sino en binario. entero al ocupar 2 bytes estamos suponiendo que ocupará las direcciones 1500 y 1501. La dirección de memoria RAM la cual almacena puntero(p) corresponderá a la dirección base de otra variable(var) que está memoria. al efectuar su declaración se debe anteponer un asterisco. La abstracción que se debe hacer es la de que P apunta o señala a VAR. Se puede definir un puntero de cualquier tipo básico o de tipos estructurados. p ┌────┐ │ │ └────┘ entero ┌─────────┐ │ 1 │ 3 │ └────┴────┘ 1500 1501 1500 es la dirección base de la variable entero. Observe que el 13 almacenado en la variable entero no está en base 10 como es mostrado. decimos entonces que el puntero "apunta" a esta variable. cuando esté ejecutándose el programa) en memoria. la variable P almacena un valor de 1000. al identificador del mismo. estos dos bytes son el desplazamiento(offset) de la variable entero. de siguiente forma: P ┌────┐ │1000│ └────┘ VAR ┌───────────────────────┐ │ │ └───┴───┴───┴───┴───┴───┘ 1000 En un en la "P apunta a VAR" 1000 es una dirección(ficticia en nuestro ejemplo. A continuación el puntero p tomará la dirección de la variable entero: p = &entero. en memoria el efecto es el siguiente: 47 . la verdadera la dará el sistema operativo por intermedio del compilador. se lee esta instrucción así: "la dirección(&) de la variable entero se asigna a la variable puntero p". PUNTERO A ENTERO El siguiente es un ejemplo con un puntero que apuntará a un entero(recuerde que un entero ocupa 2 bytes en memoria): int *p. memoria un puntero ocupa 2 bytes. INTRODUCCIÓN Los punteros son variables las cuales guardan direcciones de memoria RAM.

real=4. de esta forma en memoria las variables quedarán así: p ┌────┐ │1500│ └────┘ entero ┌─────────┐ │ 2 │ 1 │ └────┴────┘ 1500 1501 el 13 ha sido destruido al efectuarse la asignación *p = 21. PUNTERO A VARIABLE DE PUNTO FLOTANTE Los punteros pueden apuntar a variables de cualquier tipo. se leerá "al valor al que apunta p se le asigna 21". ha sido definida como un puntero a un entero. y estamos suponiendo que ocupará las direcciones 2500 a la 2503. A continuación el puntero pf tomará la dirección de la variable real: 48 . en este caso la variable p.67 │ └────┴────┴────┴────┘ 2500 2501 2502 2503 2500 es la dirección base de la variable real. apuntarará a una variable. como sabemos este última tipo de variables ocupan 4 bytes en memoria.p ┌────┐ │1500│ └────┘ entero ┌─────────┐ │ 1 │ 3 │ └────┴────┘ 1500 1501 Si se quiere visualizar el valor de la variable entero a través del puntero escribiremos la siguiente instrucción: cout << *p. 3. *p debe ser leído como: "el valor al cual apunta p". además y es lo más importante. De similar forma podremos efectuar una lectura por teclado y asignarselo a la variable entero a través del puntero con la instrucción: cin >> *p. pf ┌────┐ │ │ └────┘ real ┌───────────────────┐ │ 4. esto se efectúa así: *p = 21. sabemos. y para saber cual es el valor al cual apunta p. debemos conocer la dirección que almacena. de punto flotante. real. A través del puntero podemos. para saber cual es el valor al que apunta p. Está mostrará el valor de 13 en pantalla. debemos "saber" la dirección que tiene almacenada p y a qué tipo de datos apunta. modificar el valor de la variable a la cual esté apuntando.67. otra vez. en el siguiente ejemplo un puntero. real ocupa 4 bytes en RAM. pf. estos cuatro bytes son el desplazamiento(offset) de la variable real. la sintaxis de la declaración será: float *pf.

otra vez.2. debemos "saber" la dirección que tiene almacenada pf y a qué tipo de datos apunta. la cual corresponde a la siguiente abstracción: vector pv 0 1 2 3 4 <---índices ┌────┐ ┌───────┬───────┬───────┬───────┬───────┐ │ │ │ 17 │ 2 │ -6 │ 3 │ 28 │ └────┘ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ direcciones---> 500 501 502 503 504 505 506 507 508 509 Para hacer que el puntero. se leerá "al valor al que apunta pf se le asigna -23. de esta forma en memoria las variables quedarán así: pf ┌────┐ │2500│ └────┘ real ┌───────────────────┐ │ -23. 4.56 │ └────┴────┴────┴────┘ 2500 2501 2502 2503 el 4. pv. en memoria nos no imaginaremos así: pf ┌────┐ │2500│ └────┘ real ┌───────────────────┐ │ 4.pf = &real.3.67 ha sido destruido al efectuarse la asignación *pf = -23. De similar forma podremos efectuar una lectura por teclado y asignarselo a la variable entero a través del puntero con la instrucción: cin >> *pf.56". *pf debe ser leído como: "el valor al cual apunta pf". A través del puntero podemos modificar el valor de la variable a la cual esté apuntando: *pf = -23. y para saber cual es el valor al cual apunta pf. tome la dirección base del vector se debe 49 .56. escribiremos la siguiente instrucción: cout << *pf. vector[5] = {17.-6.67 │ └────┴────┴────┴────┘ 2500 2501 2502 2503 Para mostrar el valor de la variable real por medio puntero pf.28}.56. en este caso p sabemos ha sido definido como un puntero a un float.67 en pantalla. PUNTERO A UN VECTOR Supongamos tenemos la siguiente declaración de variables: int *pv. se lee esta instrucción así: "la dirección(&) de la variable real se asigna a la variable puntero pf". debemos conocer la dirección que almacena. Mostrará el valor de 4. para saber cual es el valor al que apunta pf.

aparecerán: 17 2 -6 3 28. vector[1]. En este caso la variable vector tiene una dirección base de 500 y un desplazamiento de 2bytes*5=10 bytes. vector[3] y vector[4]. esto se codificará así: pv = vector. 506. al ser un entero se desplazará en dos bytes.escribir la siguiente instrucción: pv = vector. pv. el índice es el que "avanza" en el arreglo. cambiando la dirección del puntero. quedaría así: vector 50 . i<5. es decir que de 500 pase a 502. según el siguiente fragmento: for(i=0. vector. 508 las cuales son las posiciones base de cada uno de los elementos enteros del vector: vector[0]. la variable pv cada que se le "suma uno" se incrementará según el tipo de datos al que apunta. El anterior arreglo. es decir apunta todo el tiempo a la dirección base. después de esto. i++. La abstracción que debemos tener quedará: vector pv 0 1 2 3 4 <---índices ┌────┐ ┌───────┬───────┬───────┬───────┬───────┐ │ 500│ │ 17 │ 2 │ -6 │ 3 │ 28 │ └────┘ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ direcciones---> 500 501 502 503 504 505 506 507 508 509 Los arreglos tienen gran relación con los punteros y deben ser vistos como punteros a los cuales no se les puede cambiar la dirección(la dirección base que almacenan) es decir como punteros constantes. observe que no se coloca el operador de dirección &. desde la dirección 500 hasta 509. que nos mostrará en pantalla los valores: 17 2 -6 3 28. Diferente será si queremos avanzar en el vector. 504. pv++. i++) cout << setw(4) << pv[i]. se puede recorrer con el puntero. se puede indexar de igual forma que se hace con los identificadores de los arreglos. while (*pv && i<5){ cout << setw(4) << *pv. para entenderlo. En memoria sería muy diferente. Al ejecutar el fragmento anterior el valor en memoria de pv es de 500. Es decir que el puntero. vector[2]. veamos prueba de ejecución manual del anterior fragmento en el siguiente tabulado: ──────────────────────────────────────────────────────────────────── pv *pv while(*pv) cout<<setw(4)<<*pv pv++ ──────────────────────────────────────────────────────────────────── 500 17 verdad 17 502 502 2 verdad 2 504 504 -6 verdad -6 506 506 3 verdad 3 508 508 28 verdad 28 510 510 ??? ??? La abstracción de lo que ocurre en memoria. } En pantalla el efecto sería idéntico que en el caso anterior.

23. 8.5. 0.h> #include <conio. cout <<"\n\nPuntero p está en la dirección de memoria: " <<&p.CPP main(){ int *pE.2}. *Cadenas[] = {"Palmira ". 7. char *pC = "Esta es una demostración\n\n". 2. real = 7. cout << "N = " << N.h> #include <conio. algo inesperado. 0. cout << "\nN = " << *p.8. 4.5.h> #include <stdio. 9}. clrscr(). i.5.45. cout << "\nDigite un valor para la variable N: ".h> //PUNTERO1. -5. caracter = 'º'. } 6. mostrado como ???. vectorR[] = {3. matrizR[][3] = {4.h> //PUNTERO2. 0. eventualmente.'l'. 5.2. #include <iostream. 2. *p. p = &N.67.CPP void main(){ float N=5. Esta es una demostración del manejo de un puntero a un número real. 6."Colombia" }. cout << "\nA la variable p se le asignó el valor: " << p. "Valle ".'a'. 51 . Cadena[] = {'C'. si no se coloca la instrucción i<5 para que termine. *Cad[] = {'\0'}.7.3. en pantalla. matrizE[][3] = {4. cin >> *p. 6. entero=234. j. vectorE[] = {3. cout <<"\n\nVariable N está en la dirección de memoria: " <<p. Esta es una demostración del manejo de los punteros.pv 0 1 2 3 4 <---índices ┌────┐ ┌───────┬───────┬───────┬───────┬───────┐ │ 510│ │ 17 │ 2 │ -6 │ 3 │ 28 │??? └────┘ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ direcciones-> 500 501 502 503 504 505 506 507 508 509 510 El puntero pv apuntaría a un valor de "basura". cout << "\nN = " << N. 9.9}. y por esto mostraría. float *pR.'i'.'\0'}. cout <<"\n\nVariable N está en la dirección de memoria: "<<&N. 7. #include <iostream.

i<3.4.//No dá dirección pC++.3.4. } getch(). } cout << "\n". cout <<"caracter\t"<<*pC<<"\t"<<pC<<"\n\n". \t" << *pR << "\t" << pR << "\n\n". pC = &caracter. for (i=0. i++) { cout <<"\nvectorR[" << i << "]\t" << *pR << "\t" << pR. i<5. pR = (float *) matrizR. } cout <<"\n". cout << "VARIABLE VALOR DIRECCION\n\n". j<3. for (i=0. pE++. pE = (int *) matrizE.2. i<3. i++) for (j=0. i=0. while (*pC) { cout<<"\nCadena["<<i<<"]\t"<<*pC <<"\t"<<pC.//No dá la dirección cout <<"Cadena \t" << Cadena <<"\t" << &Cadena << "\n\n". j<3. pE = &entero. i<5. clrscr(). } getch(). cout << "entero \t" << *pE << "\t" << pE << "\n\n". 1.9. 9. for (i=0. pR = vectorR. i++) for (j=0. 0. j++){ cout <<"\nmatrizE[" <<i <<"][" <<j <<"]\t" <<*pE<<"\t" <<pE. for (i=0. cout << "VARIABLE pR = &real. pR++. cout <<"real VALOR DIRECCION\n\n". *Cad = Cadena.6}. j++){ cout <<"\nmatrizR[" <<i <<"][" <<j <<"]\t" <<*pR <<"\t"<<pR. clrscr(). pE = vectorE. i++) { cout <<"\nvectorE[" << i << "]\t" << *pE << "\t" << pE. 52 . cout <<"*Cad\t"<< *Cad<< "\t"<<Cad<<"\n\n". 2. pR++. clrscr(). 6. pE++.8.//No dá la dirección pC = Cadena. cout <<"VARIABLE VALOR DIRECCION\n\n".

} Prueba de ejecución manual se efectúa a continuación: en la función principal de pide se digite una cadena. i++) cout<<"\n*Cadenas["<<i<<"]\t"<<Cadenas[i]<<"\t"<<&Cadenas[i]. } cout <<"\n". Invierte una cadena de caracteres. cout << "\n ". getch(). #include <iostream. return. invierte(cadena). debido a esto 53 .CPP void invierte(char *C){ if (*C) { invierte(++C). } 7.h> #include <stdio. un terminador nulo '\0' después del último caracter válido. putchar(*(--C)). return 0. getch(). gets(cadena).h> //RCADINVE. cout << "Digite cadena: ". esta debe ser leída como "si el valor al que apunta C es verdadero" C tiene un valor de 1000. i<3. por la instrucción de lectura gets. al ser cadena un arreglo se pasa su dirección base es decir 1000. recuerde que es colocado. supongamos la palabra CALI. } } void main(){ char cadena[10]. imaginemos la situación así: Pantalla CADENA (en RAM) ┌─────────────────────────┐ 0 1 2 3 4 5 6 7 8 9 │ Digite cadena: CALI │ ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ │ │ │C │A │L │I │\0│ │ │ │ │ │ │ │ └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘ │ │ └─────────────────────────┘ A continuación es invocada la función invierte. ocurriendo lo siguiente: Invierte(1000) ┌──────┐ │ C │ │ 1000 │ └──────┘ Ya en la función y en la instrucción if(*C). clrscr().i++. pasando como parámetro el identificador de cadena. for (i=0.

el if(*C) será verdadero debido a que C apunta a la dirección 1001 donde está la letra 'A'. empero antes se produce el incremento de la instrucción ++c. se ha recibido la dirección 1001 en la variable C. este último valor es el que es pasado a la función: ┌──────┐ │ C │ │ 1000 │ │ 1001 │ └──────┘ Invierte(1001) ┌──────┐ │ C │ │ 1001 │ │ │ └──────┘ En el ámbito de la invocación de esta función ocurre algo similar. Se entra en este if y se produce una invocación recursiva de la función Invierte. o en otras palabras apunta a cadena[0]. Invierte(1002) ┌───────────────────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ C │ │ C │ │ C │ │Digito Cadena: Cali│ │ 1000 │ │ 1001 │ │ 1002 │ │ │ │ 1001 │ │ 1002 │ │ 1003 │ ┌──────┐ │ C │ │ 1000 │ │ 1001 │ └──────┘ ┌──────┐ │ C │ │ 1001 │ │ 1002 │ └──────┘ ┌──────┐ │ C │ │ 1002 │ │ 1003 │ └──────┘ 54 . pasando de 1000 a 1001. se decrementa inicialmente al puntero C así: Invierte(1003) ┌──────┐ │ C │ │ 1003 │ │ 1004 │ │ 1003 │ └──────┘ por consiguiente C apunta a la letra I en el vector cadena. C tiene el valor de 1004 y en esta dirección está almacenado un nulo. se incrementará C a 1002 y se pasará como parámetro en otra invocación recursiva: ┌──────┐ │ C │ │ 1000 │ │ 1001 │ └──────┘ ┌──────┐ │ C │ │ 1001 │ │ 1002 │ └──────┘ Invierte(1002) ┌──────┐ │ C │ │ 1002 │ │ │ └──────┘ se sigue invocando recursivamente otras dos veces. en esta posición está almacenada la letra 'C' esto quiere decir que el if(*C) es verdadero. terminando la función y volviendo al sitio en que fué invocada anteriormente. en pantalla aparecerá la letra I. ya en esta putchar(*(--C). verifíquelo usted mismo: Invierte(1003) ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ C │ │ C │ │ C │ │ C │ │ 1000 │ │ 1001 │ │ 1002 │ │ 1003 │ │ 1001 │ │ 1002 │ │ 1003 │ │ │ └──────┘ └──────┘ └──────┘ └──────┘ Invierte(1004) ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ C │ │ C │ │ C │ │ C │ │ C │ │ 1000 │ │ 1001 │ │ 1002 │ │ 1003 │ │ 1004 │ │ 1001 │ │ 1002 │ │ 1003 │ │ 1004 │ │ │ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ if(*C) apunta a un nulo.apunta a la posición base del vector cadena. retornando a la invocación anterior. por esto es falso y por consiguiente se sale de la función.

h> //RLARGCAD. donde está la letra A. } else 55 . en el main(). decrementándose C de 1001 a 1000. de esta forma C apunta a la dirección 1001. terminando el algoritmo. se decrementa C de 1002 a 1001. ya aquí en la instrucción putchar(*(--C) se decrementa C. de 1003 a 1002. y a continuación se escribe en pantalla el caracter L. de nuevo en putchar(*(--C). escribiéndola en pantalla: ┌───────────────────┐ │ │ │Digite Cadena: Cali│ │ │ │ILA │ │ │ └───────────────────┘ ┌──────┐ │ C │ │ 1000 │ │ 1001 │ └──────┘ Invierte(1001) ┌──────┐ │ C │ │ 1001 │ │ 1002 │ │ 1001 │ └──────┘ Termina esta invocación y se devuelve a la anterior. #include <iostream.CPP Longitud(char *p){ if(*p) { p++.h> #include <stdio. return (1 + Longitud(p)). a la que fué llamada 8. Se calcula la longitud de una cadena de caracteres utilizando recursión.│I │ └───────────────────┘ └──────┘ └──────┘ └──────┘ es decir en Invierte(--C). ┌───────────────────┐ │ │ │Digito Cadena: Cali│ │ │ │IL │ │ │ └───────────────────┘ ┌──────┐ │ C │ │ 1000 │ │ 1001 │ └──────┘ ┌──────┐ │ C │ │ 1001 │ │ 1002 │ └──────┘ Invierte(1002) ┌──────┐ │ C │ │ 1002 │ │ 1003 │ │ 1002 │ └──────┘ Ahora a la invocación anterior. Se termina la función devolviéndose. ya que es el que está en la dirección 1002. apuntando C al caracter C y escribiéndolo en pantalla: ┌───────────────────┐ │ │ │Digite Cadena: Cali│ │ │ │ILAC │ │ │ └───────────────────┘ Invierte(1000) ┌──────┐ │ C │ │ 1000 │ │ 1001 │ │ 1000 │ └──────┘ Retorna esta vez a la intrucción siguiente originalmente.

56 . cin >> p->alto. cout << "Edad: ".return (0). //variable local *aux= *a. cout << "Digite un real para almacenar en variable A: ".b.CPP #include <iostream. float alto. } 9. struct persona{ char nombre[20]. cin >> p->edad.h> typedef struct persona PERSONA. cout << p->nombre << " " << p->edad << " " << p->alto. } void main(){ PERSONA amigo. cin >> b. cin >> a. //FUNCION8. *a = *b. } main(){ int a. } 10. por medio de una invocación de una función por referencia al estilo del C.h> #include <stdio. cout << "Longitud: " << Longitud(palabra). cout << "Altura: ". *p. El siguiente algoritmo presenta el intercambio del valor de dos variables en la memoria RAM del computador. El siguiente es un ejemplo en el cual un puntero "apunta" a un registro(struct). cout << "Digite un real para almacenar en variable B: ". *b = *aux. p = &amigo. gets(palabra). cout << "Nombre: ". cout << "Digite Una cadena: ".h> #include <conio. int *b){ int *aux. //PUNTERO3.h> IntercambioEnMemoria(int *a. Ver el siguiente capítulo para la definición de este tipo de datos estructurado. } void main(){ char palabra[30]. int edad.CPP #include <iostream. gets(p->nombre). clrscr().

A ahora es igual a "<<a. &b).IntercambioEnMemoria(&a. cout <<"\nDespués de intercambiadas. cout << "\ny la variable B ahora es igual a " << b. } 57 .

Col < MaxCol. cout << endl.11.h> const int MaxFila=5. Advertencia: Alguna vez puede que le falle este programa debido a la forma que se define la variable *cadena. Fila. A continuación se presenta una demostración de como el lenguaje C maneja cada posición de un arreglo bidimensional por medio de punteros. El siguiente algoritmo en lenguaje C ordena alfabéticamente. se le explicará esto en el capítulo sobre cadenas. más adelante. } getch(). Recuerde que un arreglo bidimensional es solamente un arreglo de arreglos. //PMATRI12. i<strlen(cadena). Col++){ Matriz[Fila][Col]= Fila*Col+1.CPP #include <iostream. aux.h> #include <string. Fila < MaxFila.h> #include <stdio. gets(cadena). cout << "Longitud cadena = " << strlen(cadena) << "\n\n". } 12. cout << setw(10) << Matriz[Fila][Col]. Fila++) { for ( Col = 0. Fila++){ for ( Col = 0. } cout << endl. void main(){ int Matriz[MaxFila][MaxCol]. j++) if(cadena[i] > cadena[j]){ aux = cadena[i]. cadena[i] = cadena[j]. cadena[j] = aux. j<strlen(cadena).h> #include <conio. j. MaxCol=4. en forma ascendente.h> #include <iomanip. for ( Fila = 0. Fila < MaxFila. for ( Fila = 0. int i.h> #include <conio. //PUNTERO11.h> void main(){ char *cadena. for(i=0. cadena de caracteres. cout << "Digite una frase: ". } cout << "\"frase ordenada alfabéticamente\": \n" . i++) for(j = i+1. } } 58 . Col < MaxCol. Col. puts(cadena). Col++) cout << setw(10) << *( *(Matriz+Fila) + Col) .CPP #include <iostream.

CPP #include <iostream. j++) if (v[i] > v[j]){ aux = v[j]. while (i < N){ gotoxy(10. v[j]= v[i]. cin >> v[i++].j. Escribir(numeros). j < N. i < N. //PUNTERO13. } } Ordenar(int *v){ int i.h> #include <conio. cout << "\n\tLos números ordenados son:\n\n". cout << "Digite " << " números". i++) for (j = i+1. } } Escribir(int *v){ int i.width(5). Ordenar(numeros).13.h> #define N 10 Leer(int *v){ int i=0. Leer(numeros). gotoxy(10. i < N.aux .4+i). num. cout << v[i]. while (!kbhit()). } 59 . for (i = 0. } } void main(){ int numeros[N]. clrscr(). for (i = 0. v[i] = aux. Se digitan N números se almacenan en vector y luego se ordenan.2). i++){ cout.

14. cin >> N. 60 . ). decimal. *r = c % 2. j. // busca el final de la cadena // escribe el binario adecaudamente } PROGRAMA A REALIZAR COMO EJERCICIO Dibuje en forma gráfica rectángulo con divisiones. Efectue a continuación lectura con la función LeerInt(. cout << "Digite un entero para convertirlo a binario: ".h> int leer(){ int N. cout << "\n\nbinario = " . de cada uno de los enteros en sus respectivas posiciones. la cual encontrará en el programa IO_Graph. en capítulo más adelante se le explicarán los conceptos básicos para poder entender el algoritmo contenido en ella). CalcularBinario(decimal. binario[20].h> #include <conio. j--) cout << binario[j]. c >>= 1.CPP (utilícela solo como herramienta. while(binario[b]==1 || binario[b]==0) b++. decimal = leer(). for(j=b-1. *r = 2. clrscr().. el cual represente un vector de N posiciones en las cuales almacenará enteros. while(c){ r++. //PUNTERO14. Este programa convierte un decimal a binario. binario). muestre en pantalla la correspondiente clasificación paso a paso(step by step). Luego utilizando función de ordenamiento de números enteros cualquiera y presentada en este capítulo. return (N). int *r){ int c. *r = N % 2. } r++.CPP #include <iostream. j>=0. //se utiliza el dos como terminador } void main(){ int b=0. } void CalcularBinario(int N. c = N >> 1.

X ahora es igual a " cout << "\ny la variable Y ahora es igual a " << Y. supongamos.CPP #include <iostream.1 │ │ 7. *b = aux. } void main(){ float X. el cual puede producir una función.PASO DE PARÁMETROS POR REFERENCIA 1. *a = *b. //REFEREN1. esto no es posible (ver módulo anterior). float *b){ float aux. IntercambioEnMemoria(&X. FORMA TRADICIONAL DEL LENGUAJE C. cout << "Digite un real para almacenar en variable X: ". en la función main del programa anterior. } Inicialmente. cin >> X. getch(). &Y). cin >> Y.1 El siguiente algoritmo presenta el intercambio del valor de dos variables en la memoria RAM del computador.h> #include <conio. cout << "Digite un real para almacenar en variable Y: ". Para entender esto estudiemos el programa REFEREN1. clrscr(). consiste en el paso de parámetros por referencia. que después de esto. se pide ser digitados los valores de las variables X y Y.h> void IntercambioEnMemoria(float *a. por medio de una invocación de una función por referencia al estilo del C. en el cual cada variable pasada como parámetro. //variable local aux= *a. Otra forma de comunicación. Y. adicional al retorno de un valor. puede ser modificada por las instrucciones contenidas en el ámbito de la función.CPP a continuación: 1. la memoria RAM se encuentra así: RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ │ │ X Y │ │ │ ┌──────┐ ┌───────┐ │ │ │ │ 13.4 │ │ │ 61 . << X. Recordemos que cuando una variable es pasada como parámetro por valor. cout << "\nDespués de intercambiadas.

Las tres instrucciones del cuerpo de la función IntercambioEnMemoria() realizan lo siguiente: aux = *a.4. esto significa que se pasan las direcciones en RAM de las dos variables. en memoria sería: RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ X Y │ a b aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ ┌──────┐ ┌───────┐ │ │ │ 13. la instrucción: *b = aux. veamos: RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ X Y │ a b aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ ┌──────┐ ┌───────┐ │ │ │ 7. estas son recibidas por los punteros a entero *a y *b.4 │ │ │ 1000 │ │ 1002 │ │ 13.4 │ │ │ 1000 │ │ 1002 │ │ │ │ │ └──────┘ └───────┘ │ └───────┘ └──────┘ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Se define adicionalmente la variable local aux.│ └──────┘ └───────┘ │ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Se invoca la función IntercambioEnMemoria pasando los parámetros &X y &Y.4 │ │ 7.1 │ │ 7. Supongamos que estas direcciones son 1000 y 1002.1 │ │ │ └──────┘ └───────┘ │ └───────┘ └──────┘ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Continúa: *a = *b. es decir que la dirección 1000 de la variable X tomará el valor de la dirección 1002 que es 7.4 │ │ │ 1000 │ │ 1002 │ │ 13.1 │ │ │ └──────┘ └───────┘ │ └───────┘ └──────┘ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Finalmente.1 │ │ 7. la cual debe ser leída como: "a la dirección a la que apunta la variable a se le asigna el valor al que apunta la variable b". y no sus valores. su efecto en memoria RAM es: RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ X Y │ a b aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ ┌──────┐ ┌───────┐ │ │ │ 13. 62 .

} CalcularBinario(int N.que se leerá como: "A la dirección a la que apunta b se le asigna el valor de aux. #include <iostream. c = N >> 1. } return 0.1 │ │ │ └──────┘ └───────┘ │ └───────┘ └──────┘ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Terminando la función y volviendo el flujo del programa a la instrucción a continuación de la invocación de IntercambioEnMemoria. clrscr().2 Convierte un decimal a binario. return (N). 1. cin >> N.h> //PUNTERO6. quedando finalmente: RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ X Y │ a b aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ ┌──────┐ ┌───────┐ │ │ │ 7.r.CPP int leer(){ int N.4 │ │ 13.4 │ │ 13. *p = c % 2. int *p){ int c. Se presenta ejemplo de paso de parámetro por referencia.1 │ │ │ │ └──────┘ └───────┘ │ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Y por lo tanto. cout <<"\n Leer desde abajo hacia arriba" << *p. while(c){ p++. las variables locales se destruyen. Recordar que cuando termina una función. c >>= 1.1 │ │ │ 1000 │ │ 1002 │ │ 13. cout << "Digite un entero para convertirlo a binario: ". por esto en este momento tendremos en RAM: ┌────────────────────────┬─────────────────────────────────┐ │ X Y │ │ │ ┌──────┐ ┌───────┐ │ │ │ │ 7. *p = N % 2. X y Y.h> #include <conio. cout << "\n" << *p. que mostrará en pantalla. estos son los valores para cada una de las variables. } main(){ 63 .

width(4). CalcularBinario(decimal. while(*i) { j = i+1. cout << *v++. } 1.4+i). *i = *j. gotoxy(10. Leer(int *v){ int i=0. } } Ordenar(int *i){ int *j. decimal = leer(). cout << "Digite " << N << " números". binario). decimal. cin >> v[i++]. aux . while (i < N) { gotoxy(10. #include <iostream.CPP const int N=10. return 0.h> #include <conio. } j++. } 64 . Leer(vector). Escribir(vector). } } Escribir(int *v){ cout <<"\n\tLos números ordenados son:\n\n". Ordenar(vector). while(*v){ cout.int i. clrscr(). while(*j) { if (*i > *j){ aux = *i. } i++. while (!kbhit()).h> //PUNTERO8. *j = aux. return 0.3 Se digitan N números se almacenan en vector y luego se ordenan. binario[20]. getch(). } } void main(){ int vector[N].2).

i++) cout << setw(5) << v[i]. while (i < N){ gotoxy(10. for (i = 0. #include <iostream. j++) if (v[i] > v[j]){ aux = v[j]. } 2. for (i = 0. i < N. clrscr().h> #include <iomanip.2). i < N. v[j]= v[i]. } } Ordenar(int *v){ int i. Leer(int *v){ int i=0. } } void main(){ int numeros[N].CPP const int N=10. v[i] = aux.4 Se digitan N números se almacenan en vector y luego se ordenan. cin >> v[i++].aux .1. gotoxy(10.4+i). j < N.j. num.h> #include <conio. Ordenar(numeros). i++) { for (j = i+1. cout << "Digite " << " números". NUEVA FORMA DEL C++ En el C++. se puede pasar por referencia el parámetro 65 . Escribir(numeros). Leer(numeros). cout << "\n\tLos números ordenados son:\n\n". while (!kbhit()). } } } Escribir(int *v){ int i. adicionalmente.h> //PUNTERO9.

CPP a continuación: 2. la memoria RAM se encuentra así: ┌────────────────────────┬─────────────────────────────────┐ │ X Y │ │ │ ┌──────┐ ┌───────┐ │ │ │ │ 13. cin >> Y. clrscr().h> #include <conio. supongamos. } Inicialmente. Estos son recibidos por las variables &a y &b. Y).real(verdadero) de una función de la siguiente forma: En la invocación se pasa la variable de igual forma que se hace por valor.1 │ │ 7. esto significa que se pasan los valores en RAM de las dos variables. y no sus direcciones. que después de esto. de la siguiente forma: RAM ┌────────────────────────┬─────────────────────────────────┐ 66 . por medio de una invocación de una función con parámetros por referencia al estilo del Pascal en C++. esto es una "desventaja" ya que al ver la instrucción no nos daríamos cuenta si se está pasando por referencia o valor. empero para estar seguros debemos ver la definición de la función. << X. &. //REFEREN3. } void main(){ float X. b = aux. //El & daría error en C aux = a. X ahora es igual a " cout << "\ny la variable Y ahora es igual a " << Y. de esta forma.CPP #include <iostream.1 El siguiente algoritmo presenta el intercambio del valor de dos variables en la memoria RAM del computador.4 │ │ │ │ └──────┘ └───────┘ │ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Se invoca la función IntercambioEnMemoria pasando los parámetros X y Y. en la función main() del programa anterior. cout << "\nDespués de intercambiadas. lo que significa que en la misma dirección de memoria se definirán a y b. IntercambioEnMemoria(X. se le antepondrá el operador de dirección. cout << "Digite un real para almacenar en variable Y: ". la costumbre nos haría pensar que es por valor. veamos el programa REFEREN3. cout << "Digite un real para almacenar en variable X: ". Y.h> void IntercambioEnMemoria(float &a. en la definición de la función. cin >> X. a = b. float &b){ float aux. en la memoria RAM tomará la misma dirección del parámetro de invocación. se pide ser digitados los valores de las variables X y Y. al identificador que recibe.

RAM ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ (a) (b) │ │ │ X Y │ aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ │ │ │ 7.│ main() │ IntercambioEnMemoria() │ │ (a) (b) │ │ │ X Y │ aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ │ │ │ 13. la instrucción: b = aux.4 │ │ 7. Las tres instrucciones del cuerpo de la función IntercambioEnMemoria() realizan lo siguiente: aux = a. ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ (a) (b) │ │ │ X Y │ aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ │ │ │ 7.4 │ │ │ 13. el efecto en memoria RAM es: ┌────────────────────────┬─────────────────────────────────┐ │ main() │ IntercambioEnMemoria() │ │ (a) (b) │ │ │ X Y │ aux │ │ ┌──────┐ ┌───────┐ │ ┌───────┐ │ │ │ 13.4 │ │ │ 13. por esto en este momento tendremos en RAM: ┌────────────────────────┬─────────────────────────────────┐ │ X Y │ │ │ ┌──────┐ ┌───────┐ │ │ │ │ 7.1 │ │ 7.1 │ │ │ 13.1 │ │ 7. las variables locales se destruyen.1 │ │ │ └──────┘ └───────┘ │ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Finalmente.1 │ │ │ └──────┘ └───────┘ │ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Terminando la función y volviendo el flujo del programa a la instrucción a continuación de la invocación de IntercambioEnMemoria.4 │ │ │ │ │ │ └──────┘ └───────┘ │ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Se define tambien la variable local aux.1 │ │ │ │ └──────┘ └───────┘ │ │ 67 .1 │ │ │ └──────┘ └───────┘ │ └───────┘ │ │ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Continúa: a = b.4 │ │ 13. Recordar que cuando termina una función.4 │ │ 13.

estos son los valores para cada una de las variables. al nuevo estilo del C++. 2. while(c){ r = c % 2. //invocación por referencia CalcularBinario(decimal). cout << "Digite: ".2 Ejemplo de paso de parámetro por referencia Convierte un número en base 10 a base binaria. cout << "\n" << r << " Leer de abajo hacia arriba". c = N >> 1. cin >> N. #include <iostream.3 Ejemplo de paso de parámetro por referencia Convierte un número en base 10 a base binaria al nuevo estilo del C++. } } void main(){ int decimal. c = N >> 1.h> #include <conio. //invocación por valor } 2.│ 1000 1002 │ │ └────────────────────────┴─────────────────────────────────┘ Y por lo tanto.h> //REFEREN2. #include <iostream. // divide entre dos r = N % 2.h> #include <conio. r. c >>= 1.//observe que N al ser puntero se coloca sin & } CalcularBinario(int &N){ int c. while(c){ r = c % 2. // divide entre dos r = N % 2.CPP leer(int &N){ cout << "Digite: ". leer(decimal). //observe que N al ser puntero se coloca sin & } CalcularBinario(int &N){ int c.CPP leer(int &N){ clrscr(). cout << "\n" << r << " Leer de abajo hacia arriba". 68 .r. X y Y.h> //REFEREN2. que mostrará en pantalla. cout << "\n" << r. cin >> N.

} void main(){ int a. int &b){ //Esto daría error en C. cout << "Digite un real para almacenar en variable B: ". cout << "\n" << r. //invocación por referencia CalcularBinario(decimal). cin >> a. y no en C++ int aux. //FUNCION9.4 El siguiente algoritmo presenta el intercambio del valor de dos variables en la memoria RAM del computador. } 69 . } } void main(){ int decimal. leer(decimal).b. por medio de una invocación de una función con parámetros por referencia. b). //invocación por valor } 2. //variable local aux = a. b = aux.CPP #include <iostream. IntercambioEnMemoria(a. cout <<"\nAhora A = " <<a << " y B = " << b << " después del intercambio".h> IntercambioEnMemoria(int &a. cout << "Digite un real para almacenar en variable A: ". a = b.h> #include <conio. cin >> b.c >>= 1.

PROGRAMA DE ESTADÍSTICA BASICA
1. Se utiliza paso de parámetros por referencia y por valor en varias funciones.
Se utiliza la estructura de datos vector para almacenar los datos en memoria
principal, pudiendo grabar y recuperar desde disco. Adicionalmente se presente un
gráfico de barras paralelas con los datos de cada muestra.
//ESTADIST.CPP
#include
<iostream.h>
#include
<iomanip.h>
#include
<fstream.h>
#include
<graphics.h>
#include
<math.h>
#include
<conio.h>
#include
<ctype.h>
#include
<stdlib.h>
#include
<io.h>
#include
<fcntl.h>
const int MaxArreglo = 20;
int intro_datos(float *datos) {
int t, max;
gotoxy(38,1); cout << "Digite número de items?: ";
gotoxy(63,1); cin >> max;
for(t=0; t<max; ++t) {
gotoxy(40, 2+t); cout << "Introduzca Item " << t+1 << ": ";
cin >> datos[t];
}
gotoxy(40, 3+t); cout << "Cualquier tecla y seguir..." ; getch();
return max;
}
void marco(){
int indice;
window(1,1,80,25);
clrscr();
cout<<"╔═══════════════════════════════════════════════════════════════╗";
cout<<"║
EJEMPLO DE ESTADISTICA BASICA
║";
cout<<"╠═══════════════════════════════════════════════════════════════╣";
for(indice = 5; indice < 25; ++indice)
cout<<"║
║";
cout<<"╚═══════════════════════════════════════════════════════════════╝";
window(2,7,70,23);
}
char CaracterEstaEn(char ch, char *s){
while(*s) {
if(ch == *s) return ch;
else s++;
}
return 0;
}
float CalcularPromedio(float Datos[], int N){ //PRUEBA ESCRITORIO

70

int t;
float Promedio=0, *P;
P = Datos;
for(t = 0; t < N; ++t){
Promedio += *P;
// Promedio = Promedio + *P; es lo mismo
P++;
}
Promedio /= N;
return Promedio;
}
float CalcularPromedio(float Datos[], int N){ //PRUEBA ESCRITORIO
int t;
float Promedio=0, *P;
P = Datos;
for(t = 0; t < N; ++t){
Promedio += *P;
// Promedio = Promedio + *P; es lo mismo
P++;
}
Promedio /= N;
return Promedio;
}
float CalcularMediana(float Datos[], unsigned int N){ //PRUEBA ESCRITORIO
register int t;
float temporal[MaxArreglo];
for (t=0; t<N; ++t)
temporal[t] = Datos[t]; /* copiar Datos*/
ClasificarMuestraAscendentemente(temporal, N);
return (temporal[(N-1)/2]);
}
void IntercambiarValoresDosVariables(float *a, float *b){
float aux;
aux = *a;
*a = *b;
*b = aux;
}
void ClasificarMuestraAscendentemente(float *Datos, unsigned int N){
//PRUEBA ESCRITORIO cuando sea invocada desde la funcion CalcularMediana()
int i,j;
float aux;
for (i = 0; i < N; i++)
for (j = i; j < N; j++)
if (Datos[i] > Datos[j])
IntercambiarValoresDosVariables(&Datos[i], &Datos[j]);
}
float EncontrarModa(float *Datos, int N){ //PRUEBA ESCRITORIO
register int t, w;

71

float md, AnteriorModa;
int cont, antcont;
AnteriorModa=0;
antcont=0;
for (t=0; t< N; ++t) {
md = Datos[t];
cont = 1;
for(w=t+1; w < N; ++w)
if(md == Datos[w])
cont++;
if(cont > antcont) {
AnteriorModa = md;
antcont = cont;
}
}
return AnteriorModa;
}
float BuscarMenorYMayor(float *Datos, int N, float &mayor){//PRUEBA ESCITORIO
int t;
float menor;
menor = mayor = Datos[0];
for(t=1; t < N; ++t)
if(Datos[t] < menor)
menor = Datos[t];
else
if(Datos[t] > mayor)
mayor = Datos[t];
return menor;
}
void Mostrar(float *Datos, int max){
register int t;
float total=0, porcentajes[MaxArreglo];
for (t = 0; t < max; t++)
total += Datos[t];
for (t = 0; t < max; t++)
porcentajes[t] = Datos[t] / total;
for(t = 0; t < max; ++t) {
gotoxy(32,1+t);
cout << setfill('.') << setw(2) << t+1 << setiosflags(ios::fixed)
<< setiosflags(ios::showpoint) << setiosflags(ios::right)
<< setprecision(2) << setw(10) << Datos[t]
<< setw(10) << porcentajes[t]*100 << "%";
}
gotoxy(35,4+t);
cout <<"Cualquier tecla y seguir...
";
getch();
}
float DesviacionEstandard(float *Datos, int max){//PRUEBA ESCRITORIO
register int t;

72

float DesvStd=0, Promedio;
double aux;
Promedio = CalcularPromedio(Datos,max);
for(t = 0; t < max; ++t)
DesvStd += ((Datos[t] - Promedio) * (Datos[t] - Promedio));
if(max)
DesvStd /= max;
DesvStd = sqrt(DesvStd);
return DesvStd;
}
void GraficarPorcentajes(float *Datos, int max){//PRUEBA ESCRITORIO
int
ManejadorGrafico, ModoGrafico;
int i, izquierda, arriba, ancho, abajo, profundidad;
float total=0;
float porcentajes[MaxArreglo];
if (max){
for (i = 0; i < max; i++)
total += Datos[i];
for (i = 0; i < max; i++)
porcentajes[i] = ((float) Datos[i]) / total;
detectgraph(&ManejadorGrafico, &ModoGrafico);
initgraph(&ManejadorGrafico, &ModoGrafico, "c:\\tc\\bgi");
ancho = (int)( (getmaxx()) / ((max * 2 ) + 1) );
abajo = getmaxy() - 10;
profundidad = (int) (ancho / 4);
izquierda = ancho;
setbkcolor(WHITE);
for (i = 0; i < max; i++) {
arriba = (abajo) - ((int)(porcentajes[i] * (getmaxy() - 25)));
setcolor(RED); //color de las l¡neas de cada barra
setfillstyle(i+1, i+1);
bar3d(izquierda,arriba,(izquierda+ancho),abajo,profundidad,1);
izquierda += (ancho * 2);
}
getch();
closegraph();
MarcoPresentacion();
}
}
void ImprimirEnImpresora(float *Datos, int max){
register int t;
float total=0, porcentajes[MaxArreglo];
ofstream Imprimir("PRN");
for (t = 0; t < max; t++)
total += Datos[t];
for (t = 0; t < max; t++)
porcentajes[t] = Datos[t] / total;
gotoxy(35,4);
cout <<"Imprimiendo...
";
Imprimir << "\n
Registro

Datos

Porcentajes \n\n";

73

') <<setw(5) << t+1 << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setiosflags(ios::right) << setprecision(2) << setw(15) << Datos[t] << setw(15) << porcentajes[t]*100 << "%" << endl. i++) Archivo. sizeof(float)). 3. } Imprimir << "\f". 3. "Elija letra inicial (C E O M G I T): ".open("Estadist. cout cout cout cout cout cout cout cout cout cout << << << << << << << << << << "MENU PRINCIPAL".close(). "Ordenar de menor a mayor".for(t = 0. 3). fstream Archivo. Mostrar(Datos.ica". ++t) { Imprimir << setfill('. 9). "Estad¡sticas b sicas".read( (char *)&Datos[N]. 3. ios::in | ios::binary). N=0. } void GrabarDatosEnArchivo(float *Datos. } else cout << "Archivo no existe". 4). i<N. 3. N).13). 5). sizeof(float) ) ) N++. "Capturar Datos". 74 . else{ for(i=0. clrscr(). 2). } void LeerArchivoYCargarEnDatos(float *Datos. fstream Archivo. int &N){ int IDArchivo.open("Estadist. t < max. int N){ int i. "==============". 8). if(Archivo){ while( Archivo.close().write((char *)&Datos[i]. "Terminar". if (!Archivo) cout << "Error en la apertura del archivo \a". Archivo. 3. 3.ica". 3. "Graficar en barras". 1). 7). Archivo. Archivo. ios::out|ios::binary|ios::trunc). "Mostrar Datos". "Imprimir en papel". cout << "Le¡dos desde disco: " . do { gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( gotoxy( 3. Archivo. } } char OpcionMenu(){ char entrada. 6). 3. 3.

Mostrar(Datos.. N). Mayor=0.DesvStd=0. cout <<"Máximo : "<<Mayor. exit(0). cout <<"Moda : " << Moda. N). Moda = EncontrarModa(Datos. // almacena valores de la muestra int N=0. break. Menor=0. case 'E': Promedio = CalcularPromedio(Datos.. Menor = BuscarMenorYMayor(Datos. cout <<"Desviación Std : " <<DesvStd. getch(). case 'I': ImprimirEnImpresora(Datos. gotoxy(30. Varianza = DesvStd*DesvStd. LeerArchivoYCargarEnDatos(Datos. N). N). //Número verdadero de elementos float Promedio=0. gotoxy(30. cout <<"Varianza : "<<Varianza. case 'G': GraficarPorcentajes(Datos. case 'O': ClasificarMuestraAscendentemente(Datos. entrada = AMayuscula(getch()). N). "CEOMGIT")). break. N). N). Moda=0. gotoxy(30. Mediana = CalcularMediana(Datos. } void main(){ //ESTADISTICA BASICA FUNCION PRINCIPAL float Datos[MaxArreglo]. 3). gotoxy(30.". case 'T': GrabarDatosEnArchivo(Datos. N. cout <<"Mediana : " <<Mediana. gotoxy(30.gotoxy(39. Varianza=0. for(. 7).. gotoxy(30. return entrada. case 'M': Mostrar(Datos. 1). gotoxy(30. break. 2). cout <<"Cualquier tecla y seguir. break. cout<<"Promedio : " <<Promedio. gotoxy(30.) { switch( OpcionMenu() ) { case 'C': N = Intro_Datos(Datos). N). N). 9). MarcoPresentacion().Mediana=0. break. 4). DesvStd = DesviacionEstandard(Datos. break. 5). cout <<"M¡nimo : " << Menor. N). Mayor). N). 6). } while (!CaracterEstaEn(entrada. } 75 .13).

CPP anterior para efectuar cálculos estadísticos básicos. El programa debe presentar menú diseñado por usted mismo a partir de la primera clase y todo en forma gráfica. 76 ..) la cual encontrará en el archivo IO_Graph.. Para la lectura de los correspondientes valores reales(float) utilice la función LeerFloat(. estudie y utilice el programa ESTADIST. Presente dibujo en pantalla representativo del experimento en cuestión.} } PROGRAMA A REALIZAR COMO EJERCICIO Utilizando datos obtenidos en algún laboratorio de los realizados aquí en la universidad. discuta esto primero con el profesor.CPP. y claro que dentro de otras asignaturas.

opcion.2.4.1.4. 58.2.6.2.51. 65.4. 52.0. 65. 41.4.4.4.2.51. 62. 55.1.4.51.4.4. 61.2.2.h> <IOStream. 58. Tecla[47]=15.2.0.h> <DOS. Tecla[0]=0. Tecla[67]=38.44. 52.2. char C[2]. 42. 58. char ElDanubioAzul[] = { // J.3.0.1.1.2. 42. 59.S.2. 61.4. char Sinfonia40[] 55. 50.-1}.4.4. Tecla[49]=17. -1. 66.4.1. 66.2.4.0. = { //Mozart 54.46.49. Tecla[40]= 7.4.0. Tecla[50]=18. 65.4.4. 46.1. 58. Tecla[39]= 5. Tecla[41]= 8.6.2.2.3. 41.46. 52.6. Tecla[63]=33.4.2.16.4.6. 61. 59.1. 42.1.46.2.1.4. 54.0.4. El siguiente programa permite escuchar varias melodías.4.cpp #include #include #include #include #include #include <ConIO.4. tempo=60.0. void main(){ int I. 52.4.6. 59. 64.2.54.1.30.0.4. 0.42.42.4.6.4.46.54.1.4. 0.4.2.2.4.4.0.6.2.14.30. 61. 54.49. 44.1.0.4. Tecla[59]=29.1.4. 50.h> constream Escribir.47.4. 61. 55.0.0.2.4.2.49. 50.1.4. 59.4. 66. 64. 61.2.PUNTERO A NOTAS MUSICALES 1.0. 52. 47.0.h> <Math.46.51. 52.0.4.4.42.0.0. -1. 66.0. 42.2. 59.4.2.8. 0.0. 61.4.4. 54.42. 64. Los vectores son recorridos por medio de un puntero.5. 64. 42.4. K.4. 62. Tecla[53]=22. 63.0.1. 47.4.44.2.1. 64. 42.4.35.4. 52.4.2.4.2.2. 64. 42.2.2.4.1.1.6. //Musica.0. 62. 61.0.46.1. Tecla[64]=35.0.2.h> <ConStream. Tecla[62]=32. 0. Tecla[68]=39. 62. 55.1.4.4.1.2. 50.4. 55. 52.4. 0.49. 44.2.4.44.2.6.2.5.0.0. Tecla[52]=21. 77 .1. 52. 48. 0.0. 54.1. 55.8.49.0.4.44.0. 54.4.2.2.47.37.2.2.4.0.0.2.4.5. 57.2.1.0.1.0.2.4.47. Tecla[43]=10.2. Tecla[58]=28.2.8. 54.-1}. 49. Tecla[57]=27.1.49.0. 42.0. 54.49.1.1.2. Tecla[71].2. 61.4.0.2.2.30. 0.47. 54.8. Tecla[60]=30.46.2.2.2.2. 63. 58.0.0.6.4.2. J. 0. 58.4. Tecla[46]=14.2.0. int Nota[88].42.8.58.0. 63.4.2. 54.1.2.3. 63. *p.4.4. 65.4.47. 61.6. 54.1. 47.2.2.1.42. 61. 57.51.4.42. Tecla[42]= 9.2.5. Tecla[51]=19.4.0.4.54.44.h> <CType.2. Tecla[69]=40. Las notas de estas están almacenadas en vectores.49.4.4.4. 41.0. 51.51.1.2. Tecla[70]=42. Tecla[44]=11.2.0. 59.2.2.4.8. 61. 52.0.1. 61.1.2.1.2.5. 63.2.56.0. 61.0. 42.1. 62. Tecla[56]=25.1. 54. 58.1.4. 46.2.0.4. 61.2.4. 59.0. 0.2.4.4.4.6.4.1. Tecla[66]=37.0. 49. 58.0.0.2.0.1.2.0.4.0. ModoVideo.0. 59.54. 59.4.1.2.0.1. 59.3. 0.46.54.1. 54.4. 42.1. 61. Tecla[45]=13.1. 54.1.2.8. 63. 55.1.0.1. 54. 0.2.2.4.1. Tecla[65]=36. Tecla[48]=16.0.4.5. 64. Tecla[55]=24.1.1.2. 41. Tecla[54]=23.0. 52.51.0.2.2. 65. char LaCucaracha[] = { //popular mejicano 42.1.2.46.37.51.2.1. Tecla[61]=31.Strauss 42.6.4.42.4.6.4.0.4.51.0.49. 0.49.1.2.

56.54.3.2.3.0.2. 59.0.41.59.2.0.2.3.3.2.6.2.0. 56. char YankeeDoodle[] = { // .56.0.42.2.3.51.4.3.45.2. 54.3.45. 49.2.47. 2.2.2.2.61.4.3.47.2.49.16.50.0.1.2.8.2.2.49.51.2.0.2.4.0.47.3.47.2.41.-1}.6.58.2.3.58.3.49.0.0.2.0.42.45.5. -1.49.0.49. 59.1.54.2.0. 49.51. -1.49.56.54.0.5.56.2.54.-1}.0.56.4.4.6.2.2.2.2.6.42.3.3.56.3.3.8.3.2.45.6.6.2.54. char StarsAndStripesForever[] = { //Sousa 54.3. 49.2.2.3.52.2.3.0.3. -1.0.51.62.6.3.50.0.3.54.3.56.46.1.43.Anónimo 50.51. 49.1.1.3.2.59.54.49.1.49.6.46.3.48.2.51.2.58.49.3.47.2.62.66.9.51.1.3.54.56.50.2.54.3.0.4.2.0.49.54.2.0.58.3.3.49.52.3.2.0.2.2.52.3.52.3.1.59.3.2.3.57.0.2.0. 47. 54.50.58.64.0.2.3.2.61. 0.2.2.2.3. 61.2.30.4.4.0.4.3.6.49.51.2.57.2.2.0.3.2.2.4.47.47.54.57.57.3.2.45.3.3.3.3.56.2.3.0.0.6.2.4.3.47.2.1.47.49. 0.2.1.64.3.2.3.4.49.0. 0.58.-1}.3.49.51.2. 49.6.3. 0.0.42.6.47.2.1.5.4.3.51.2.59.0.0.3.3.47.3.42.2.3.2.49. 49.9.2.2.59.52.3.2.0.0.42.0.47.37.2. 0.59.0.3.1.18.2.0.2.42.6.2.47.2.2.3.3.52.0.2.2.52.3.0.42.3.4.0.3.3.3.1.3.3.2.3.51.56.52.3.42.56.5.3.0. 0.3.3.2.0.54.2.1.3.52.4.56.54.51. 49.2.2.-1}.1.1. 49.2.50.2.49.2.2.58.39.3.0.0.0.2.0.2.2.3.2.42.47.6.51. 52.2.2.49.42.2.2.49.2.1.59.3.57. 49.57.2.2.16.64.24.50.52.50.0.47.2.52.3.0.0.2.55.2.3.51.3.2.3.56.3. 47.64.6.2.2.50.3.3.50.0.0.2.61.2.3.2.3.47.0.49.3.1.52.3.1.44.51.61.3.4.56. 54.49.44.56.3.0.2.56.50.50.47.3.3.64.0.2.56. 78 .3.54.57.2.52.16.54. 57.58.1.3.54.49. 47.2.3.4.3.51.5.52.2. char PopGoesTheWeasle[] = { // Anónimo 47.54. 56.45.3.6.61.2.54.3.2.2.47.3.59.47.3.2.42.3. -1.59.3. 47.54.3.0.50.6.2.2.3.3. 59.2.0.59.15.39.49.3.6.0.37.44.4.47.57.54.48.6.2.54.0.42.49.30.0.51.2.58.2.51.6.2.3.3.45.2.4.0.3.54.52.2.49.50.3.3. 50.0.6.-1.1.6.59. 4.3.3.2.2.3.2.49.3.6.16.12.3.4.2.8.41.2.2.42.54.59.4.49.58.0.0.3.3.50.3.2.3.3.61.2.0.6.51.0.3.6.0.51.1.3.49.1.51.50.3.2. char MarchaFuneralDeLasMarionetas[] = { // Gounod 37.41.49.56.0.37.3.39.52.1.2.2.1.41.2.3. 49.4.61.3.1.2.2.54.45.53.3. 47.0.2.58.45.6.3.3.1.6.2.9.49.51.50.51.47.2.30.6. -1.6.0.0. 30.61.56.59.6.0.2.42.3.49.1.42.44.55. 59.52.1.47.3.3.2.52.3.2. -1.50.0.1. 54.-1}.2.6.1.59.5.2.47. 41.54.2.3.2.52.0.54. 0.3.49.3.59. 2.3. 37. 51.47.4.3.52.0.1.1.54.2.0.59.56.2.2.3.45.49.3.49.1.56.2. char Humoresque[] = { // Dvorak 47.39.44.5.63.50.47.6.2.51.43.50.51.0.6.3.2.2.4.0.51.0.0.58.42.56.56.45.1. 51.2.50.54.2.41.2.0. 57.45.3.2.42.2.3.46.2.0.16.3.3.0.45.1.56.50.51.6.58.1.3.2.2.41.2.56.2.12.3.47.2.42.6. 46.3.2. 47.54.3.3.62.3.0.44.3.49.3.2.3.2.47.2.49.0.56. char PopularMejicana[] = { //Anonimo 52.42.42.3.3.4.2.47.49.49.57.3.3.3.57.42.49.49.1.2.3.2.3.3.56.3.6. 47.2.56.3.41.0.45.3.59.49. -1}.51.0.0.50.59. 54.2.3.52.0.12.2.5.47.3.63.6.4.44.52.0.3.0.47.16.3.52.6.44.2.49.52.58.52.61.2.50.-1}.2.50.2.56.52.50.59.2.0.2.53.6.3.47.3.49.3.3.3.3.8.42.3 .3.4.0.58.4.54. 62.3.2.60.50.2.0.61.51.0.2.2.47.0.1.51.3.3.2.3.5.0. 49.51.3.2. 0.3.0.0. 47.16.3.3.2.3.

8.1. 49.40.1.44. gotoxy(12.65.44.1. } clrscr(). textmode(ModoVideo). 40.4. 51. Escribir.1. -1.44.43.54. Escribir << "PROGRAMA".8.-1 }.4.8.52.1.Escribir<<(char)179<<" gotoxy(9.8.1.8.1.62.55.0.49.51.52.8. cout << " C4350 ³ 64 ³ EGA 43-lineas \n".1.1.44. Escribir << "DEMOSTRACION". cout << " C80 ³ 3 ³ Color 80 columnas\n".1.40. textcolor(LIGHTGREEN). i<=21. MUSICAL "<<(char)179.49. i++){ Nota[i]= 32767. } for (i=7.1.1.1. 61.8.51.10). for(i=1.8. gotoxy(12. char Escalas[]={ 38.61. gotoxy(9. for (int i=0.47.49.8.55.4.4.Escribir<<(char)179<<" 79 .1.51.51. 49.1. textcolor(MAGENTA).1.66. cout << " BW80 ³ 2 ³ Blanco y Negro 80 columnas\n".51.49. Escribir.44.80. cout << " LASTMODE ³ -1 ³ Modo de texto previo \n".12.42.65. cout << "\nNOTA: Para un tipo dado de monitor de video no todos funcionarán como se espera\n".45.char Sakura[] = {// Melodia folclorica japonesa 49.1. 49. Escribir<<(char)184.1. Escribir<<(char)213.8. 49. i<=21.1. y determine los que ""le sirven""\n".8. Escribir<<(char)179.8.1.1.40.1.60. cout << " C40 ³ 1 ³ Color 40 columnas\n".1. cout << "Constante ³Valor³ Modo de Texto \n".49. 0.62.41.1.1.1.41. 50.53.67. cout << " BW40 ³ 0 ³ Blanco y negro 40 columnas\n".38.57. cin >> ModoVideo.8.1.45.1.68.clrscr().4.42.45.4.25).0.1.44.1. for(i=1.1.8.64. gotoxy(9.1. cout << " ³ ³ VGA 50-lineas \n".16.-1}. (float)1/12).1.45.8.51.13).12.60.1.52.16.12.1.16.67.4.51.8.12. 48.63.45.1.1.1.56.43.8.54.4.39.40.1.1.0. cout << "ÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\n".59. i-6 ) .1.window(1. 49.11).51.4. cout <<"Ensaye cada uno para su monitor de video.8*pow( pow(2.8.5).1. i++){ Nota[i] = 36.7).68.1.50.49.1.1.39.47.46.1.1.1.48.57.49. i<88.49.1.58.45.49.46.1.64.1.4. cout << " MONO ³ 7 ³ Monocromo 80 columnas\n".53.1.59.1.1.1.8.1. textbackground(BLUE). TECLADO "<<(char)179.1.1. i<=6.8. 51.1.-1.56. 44.1.39. cout<<"\n\nDigite Valor del modo de texto deseado: ".8.1.Escribir<<(char)179. cout<< " MODOS ESTANDARD DE TEXTO \n". 0.1. i++) Escribir << (char)32.66.12).44. 63. gotoxy(9.8.8.4.8. i++) Escribir << (char)205.58.

gotoxy(37.Escribir << "-----------. 5+J). Escribir<< " gotoxy(2.Escribir << "A-Marcha E-Humoresca I-Japonesa".CANCIONES -------------". 80 . getch().17). textcolor(WHITE). Escribir<<"Digite letra ====>". textcolor(RED). textbackground(BLACK). I++) Escribir<< (char)219. gotoxy(1. J++){ //Dibuja el borde del teclado gotoxy(1. Escribir <<(char)221.5+J). } for( J=0. Escribir <<(char)221. textbackground(BLUE). for(i=1. i++) Escribir << (char)205. J<=9.15).4).19).14). textbackground(BLUE).Escribir << "B-Stars F-La Cucaracha J-Pop ". textcolor(YELLOW). gotoxy(5+I*2. gotoxy(2. p=MarchaFuneralDeLasMarionetas. I++) //Dibuja teclas negras for( J=0.Escribir<<(char)212. break. I<=36. I<=17...I<=36. textcolor(WHITE). Escribir << "CUALQUIER TECLA PARA SEGUIR".Escribir << "C-Mozart G-Danubio Azul K-Escalas ". Escribir. textcolor(WHITE). for(. gotoxy(7.Escribir << (char)221.21). Escribir << (char)219<<(char)221. 4+J).21). Escribir<<(char)190. J<=4. I<=15.Salir". 13). } textcolor(RED). for( I=0. gotoxy(3. Escribir<< (char)(221). Escribir<< (char)32<<(char)222. J<=8. gotoxy(3. textbackground(LIGHTGRAY).Escribir << "D-Mejicana H-Dandy ESC.23). switch( opcion=toupper( getch() ) ){ case 'A': Escribir<<"Marcha".4+J).16). textbackground(BLACK). I++) // Dibuja teclas blancas for(J=0. J++){ gotoxy(2+I*2. Escribir<< (char)(221). J++){ if( I==2 || I==6 || I==9 || I==13 ) continue. gotoxy(3.clrscr().18). gotoxy(3.gotoxy(9. i<=21. for( I=0.I++) Escribir<< (char)219. textcolor(RED). } for( I=0. gotoxy(3. gotoxy(1. ".){ textcolor(MAGENTA). for( I=0.

break.case case case case case case case case case case case 'B': Escribir<<"Stars". textbackground(LIGHTGRAY). if( J>=39 && J<=68 ){ gettext(Q.5. gotoxy(Q.Q.5. p=LaCucaracha. 'H': Escribir<<"Dandy ". Escribir<<(char)14. 'G': Escribir<<"Azul". p=Escalas. gotoxy(Q. p=Sakura. 'E': Escribir<<"Humoresca". break. 'F': Escribir<<"La Cucaracha". 'K': Escribir<<"Escalas ". break. p=PopGoesTheWeasle. } } sound(Nota[J]). 'J': Escribir<<"Pop". p=YankeeDoodle. int Q = Tecla[J]-3. 'D': Escribir<<"Mejicana". K=*(p+1). textcolor(BLACK). 27: return. p=Sinfonia40. p=ElDanubioAzul. break. 81 . break. textbackground(BLACK). break. if (C[0]!=32){ textcolor(BLACK). textbackground(LIGHTGRAY). break. break. if(opcion>='A' && opcion<='K'){ while(*p!=-1 && !kbhit()){ J=*p. p=PopularMejicana. } _setcursortype(_NOCURSOR). 'I': Escribir<<"Sakura". C). Escribir<< (char)14. break. p=StarsAndStripesForever. break. textcolor(WHITE). delay(K*tempo).11).7). p=Humoresque. } else{ textcolor(WHITE). 'C': Escribir<<"Cuarenta". textbackground(BLACK).

delay(tempo).11). } } 82 .7). } } p = p+2. C).if(! (J==0 && K==1) ){ sound(32767).5. } } _setcursortype(_SOLIDCURSOR). if (C[0]==32){ gotoxy(Q. } if(J>=39 && J<=68) { gettext(Q. textbackground(BLACK). Escribir<<(char)32. textcolor(WHITE). Escribir<< (char)219.5.Q. } else{ gotoxy(Q.

void Icono33(int x. void MarcoVentana(int x1. void Icono13(int x.Icono5. void Icono11(int x. int y). void Icono1(int x. int y). int y). int y).y+46. void Icono25(int x. int y). void Icono14(int x. Icono11. void Icono31(int x.x+30. //PilaVect.Icono28. void Icono4(int X. void Icono15(int x. fillellipse(x+25. void Icono34(int x.Icono26.int Color. TOP_TEXT). Icono29. int y).Icono30. int y1. settextstyle(SMALL_FONT. 1. void Icono30(int x. void Icono28(int x.Icono7.y+25.Icono24.Icono27.DARKGRAY). void Icono24(int x. y+AltoIcono. void Icono36(int x. El siguiente programa es un ejemplo de la declaración de un vector de punteros a funciones. int y).LIGHTGRAY).int Y.Icono32.h> <stdlib. void Icono22(int x.Icono8.Icono19. int y).Icono34.h> //Definición de algunas constantes ("por facilidad") const int AltoIcono=50. int y).y+10. int y){ setcolor(WHITE).Icono22. int y). outtextxy(x+AnchoIcono/2. int y). void Icono29(int x. int y). int y). int y). int Y).Icono31. void Icono3(int x.Icono6. void Icono16(int x.Icono12. int) = {Icono1.char *Cad. bar3d(x+17. 4). bar3d(x+10. int y).h> <dos. void Icono5(int x.Icono9. int Oprimido).VECTOR DE PUNTEROS A FUNCIÓN 1. //Declaración de prototipos de funciones: void Cursor(int X.y+30. int y2. } void Icono2(int x.cpp #include #include #include #include <graphics.h> <conio. void Icono2(int x. void Icono23(int x. int y). void Icono35(int x. void Icono8(int x. void Icono10(int x. Icono20.Icono13. //Funciones del programa: void Icono1(int x. 0). int y).Icono18. "Informar"). void Icono12(int x.Icono3.Icono23. int y).Icono2. 83 .Icono33. int y). int y).Icono35. void Icono9(int x. int y){ setcolor(BLUE). void Icono19(int x. void Icono27(int x. int x2. void Icono26(int x. int y).2).int pos.Icono15.Icono10. //Definición de arreglo de punteros a funciones: void (*Icono[MaxIco])(int. void Icono21(int x.Icono4. int y). int y). int y). int ColorAbajoDerecha). void Icono20(int x. void Icono17(int x. int y). int ColorArribaIzquierda.y+20.7. setfillstyle(1.Icono21.x+32. setfillstyle(1. int y). MaxIco=36.Icono16. HORIZ_DIR. int y). void Icono18(int x. int y). int y).Icono14. setcolor(MAGENTA). void Icono7(int x.12. int y). int y). int y).Icono25.Icono17. void Icono32(int x. void Icono6(int x. AnchoIcono=50. int y). settextjustify(CENTER_TEXT. int y).7).Icono36}. int y).

x+25. line(x+20.y+38).y+10.y+30. line(x+22. line(x+41.y+20).y+30). line(x+40.x+7.y+15.outtextxy(x+AnchoIcono/2. x+30.y+25.y+15). x+30.x+27.x+30.137. line(x+10.x+18.y+45).y+42).y+30). x+40. line(x+20.y+23). line(x+40.y+23.y+30. x+12.y+16). line(x+10.0).x+30.y+7. setcolor(MAGENTA). bar(x+19.y+29). line(x+10.y+35). line(x+20. 4).RED).y+20). line(x+10. setcolor(BLUE). line(x+38. line(x+30. x+32. line(x+20. 5.y+35). y+21). x+35.y+22).y+23). x+11.x+35.y+48). int y){ setcolor(DARKGRAY). line(x+30.y+22.y+30.1).y+35.y+10).y+19).y+33. line(x+40.y+15."Impresión"). x+20.x+27.x+26.y+19. y+10.y+30.BLUE). int y){ setcolor(WHITE). y+20.y+10). setcolor(BLUE).y+5.y+11). setcolor(RED). "Computo").x+10.y+40.y+44). bar(x+15. x+27. line(x+40.y+10.y+20).y+14.y+16.y+27. x+11.y+20. int y){ setcolor(DARKGRAY). line(x+20. } void Icono5(int x.y+38).line(x+31. settextstyle(SMALL_FONT. TOP_TEXT). x+25. HORIZ_DIR.y+24). setcolor(RED). 8. line(x+40. x+28.y+20.y+10. settextstyle(SMALL_FONT. y+45). setcolor(MAGENTA).x+17.7. line(x+22. line(x+29. settextjustify(CENTER_TEXT. x+22. setcolor(MAGENTA).y+30.y+41). x+29.y+38. setfillstyle(1. line(x+10.x+6.y+25. setfillstyle(1. line(x+18.3.y+21.y+13).y+13).y+29. x+40.x+35. x+26. line(x+24.x+22. line(x+7. line(x+30.LIGHTMAGENTA). y+16. 4).x+33.x+26. 8).y+10. line(x+6.y+36. y+AltoIcono.y+5).y+15.WHITE). line(x+5. line(x+27.y+20.x+27.y+23). setfillstyle(1.y+10.x+10.y+28.x+30. setfillstyle(1. x+10.369). y+46.y+3). x+20.y+30. x+24. 5). 84 .y+16.y+17). line(x+10. fillellipse(x+10. setcolor(LIGHTGRAY).y+22. TOP_TEXT).GREEN). bar3d(x+15. line(x+29. bar(x+15.y+20.y+27). fillellipse(x+25. } void Icono4(int x.YELLOW).y+33).y+10).x+36. x+40. bar3d(x+31. x+20.y+40). line(x+10.y+43). bar(x+20.y+29. line(x+30. settextstyle(SMALL_FONT.y+22. setcolor(LIGHTGRAY).y+16).y+33.outtextxy(x+AnchoIcono/2. TOP_TEXT). x+32.y+34).y+31."Personal"). line(x+12. x+31.setfillstyle(1. line(x+25. x+36.y+10. setcolor(DARKGRAY). line(x+10.y+45).y+14.line(x+26. line(x+25. setcolor(DARKGRAY).y+25.y+12.x+34. setcolor(WHITE).y+15).x+6. settextjustify(CENTER_TEXT. line(x+22. settextjustify(CENTER_TEXT. setfillstyle(1.line(x+31. y+AltoIcono.y+33). setcolor(DARKGRAY). setcolor(DARKGRAY).x+20.BLUE).y+30.x+40.outtextxy(x+AnchoIcono/2.y+10).y+15). y+AltoIcono.y+33.y+20). line(133. line(x+12. line(x+10.x+10.x+30.y+30). 4).x+25.y+32. x+20.y+25). setfillstyle(1.y+5.y+15.y+45. x+25.y+10). line(x+35.y+5).364. y+10.y+40.y+20). HORIZ_DIR. y+48).x+28. } void Icono3(int x. line(x+20. HORIZ_DIR. line(x+22. setcolor(RED). line(x+39. line(x+18. line(x+20. x+29.y+38).y+31.

fillellipse(x+12.y+32. settextjustify(CENTER_TEXT. bar(x+18.x+35.y+30. 4).10.YELLOW).y+35.y+11.x+20.y+31). bar3d(x+5.y+10.y+35. setcolor(DARKGRAY).1.y+45.1.WHITE).0).line(x+38. bar3d(x+7.y+36."Almacen"). line(x+12. setfillstyle(1.y+35. bar3d(x+45.y+37.x+35.y+43. settextjustify(CENTER_TEXT.x+10. int y){ setfillstyle(1.LIGHTGREEN). line(x+13.y+24.y+35). arc(x+10.outtextxy(x+AnchoIcono/2. line(x+22.1. line(x+13.1.y+20). y+AltoIcono.1.y+24).x+18. y+AltoIcono. setcolor(LIGHTGRAY).y+22). circle(x+36.x+38.y+5.setfillstyle(1.1.y+28). } void Icono9(int x.y+40).x+15.outtextxy(x+AnchoIcono/2. bar3d(x+5. YELLOW).line(x+38.1).YELLOW). setcolor(MAGENTA). HORIZ_DIR.x+15.line(x+12.y+32.y+37.y+35.x+28.y+37).x+35. TOP_TEXT). settextjustify(CENTER_TEXT. line(x+15.y+30.y+25).y+35.y+30).x+47.y+5. settextstyle(SMALL_FONT.x+15. setfillstyle(1.x+22.y+40).y+7.y+15.x+30."Par bola"). line(x+13. bar(x+15.0).x+35. bar3d(x+7.y+40. line(x+12.y+20.x+12.y+36.y+36. bar(x+20.3).y+35.y+20.WHITE). } void Icono6(int x.1. line(x+44.x+40. y+AltoIcono. line(x+12.x+22. bar(x+10. line(x+13. line(x+35.y+47. line (x+20. 4). setcolor(WHITE). circle(x+29. bar3d(x+20. y+AltoIcono.20). line(x+38. TOP_TEXT).y+7). settextstyle(SMALL_FONT.630.x+28.DARKGRAY). bar3d(x+15.x+27.x+28.x+22. line(x+20. } void Icono7(int x. HORIZ_DIR.y+13). settextstyle(SMALL_FONT.x+20.x+28.y+17. TOP_TEXT). settextjustify(CENTER_TEXT. int y){ setcolor(DARKGRAY). int y){ 85 . int y){ setcolor(RED). 4). line(x+15. } void Icono8(int x.outtextxy(x+AnchoIcono/2.y+25.1.y+30).x+42.1).y+28. setfillstyle(1. setfillstyle(1.0).y+28.y+28.0).1.y+19).y+37).y+24).x+28. } void Icono10(int x.y+15.WHITE).x+44. HORIZ_DIR.y+10. TOP_TEXT). line(x+22. setcolor(MAGENTA).x+35.y+28.y+15. bar3d(x+7.y+10.y+17.y+20).x+35. int y){ setfillstyle(1.x+30. line(x+15.y+28).y+40)."Archivos").x+13.y+39).y+10.y+23.y+23.0).y+40.x+12. settextstyle(SMALL_FONT. settextjustify(CENTER_TEXT. setfillstyle(1.y+30.3). y+AltoIcono.y+20). HORIZ_DIR. line(x+27.y+10.x+32.y+24).x+44.x+35.x+40.0). HORIZ_DIR.y+10).y+19."Gerencia"). line(x+30. 4). TOP_TEXT).y+10.y+39).0).y+10."Listados").y+39).370. settextstyle(SMALL_FONT.x+13. setfillstyle(1.y+37. 4). DARKGRAY).y+10. line(x+12.y+37).y+40).outtextxy(x+AnchoIcono/2. line (x+25.x+27.y+27.y+31).y+25.outtextxy(x+AnchoIcono/2. setcolor(MAGENTA). bar3d(x+10.line(x+12. line(x+28.x+22. setcolor(MAGENTA). setcolor(MAGENTA).0).y+20).

bar3d(x+25.x+32.37.setcolor(RED). 29. line(x+20. 18.36. 19.23. 16. for(i=0. 25.31.42. y+AltoIcono. i+=2) putpixel(x+pica[i].y+20. 16. TOP_TEXT).45. 26.y+30). 11.y+28).41. 4).35. 19. 17. i<sizeof(diamante). HORIZ_DIR.45. 22. 24.40.1.39. 30. 19.y+20).outtextxy(x+AnchoIcono/2. 17. line(x+10. 15. line(x+15. 20.36.y+13).x+10. 13.24. line(x+14. 23.43.x+10. 22. 29.y+8).x+10.y+33). setcolor(MAGENTA). 21. setcolor(MAGENTA). 11.y+35. 20. setfillstyle(1.y+25).42. settextstyle(SMALL_FONT.y+27).49."Taller"). 20.22. lineto(x+25.x+16. 30. lineto(x+45.30.31. 11.42.35. 25. setcolor(MAGENTA). 26. 26. 15.36.y+20.37. 19.y+5).29.y+5. 24. 21. 12. y-=10. x+=5. 19.y+5).y+25).y+20). lineto(x+42.y+8). 20. 14.30.y+10). 22.24.y+25.y+45. 26.35. 30.y+8. y+30.x+15.y+30.50. 30.29.y+30). } void Icono12(int x.42. int i.27. 23.27. lineto(x+37.y+5). 22. 18.24. 86 . lineto(x+45. 28. 27.DARKGRAY).32. lineto(x+17. DARKGRAY).25.49.y+30).30.23. 12.30.33.int y){ static char diamante[] = {20.34. 20. TOP_TEXT).48.42. 15. y+diamante[i+1]. 19.26. 25. i<sizeof(pica).49.1. 18. lineto(x+23.42.28. 24. 23.49. 30. 22.21 }. settextjustify(CENTER_TEXT.21}.37. 23.RED). 19.27. for(i=0.28. floodfill(x+20.41. 21.49. TOP_TEXT).43. lineto(x+40. 26. 30. 17. 23.21.47.29. moveto(x+22. 14.y+25).38. settextjustify(CENTER_TEXT.49. 18.22. line(x+21.42. 22. 13. 11.39.outtextxy(x+AnchoIcono/2.26. 28. 11.21.32. 19. 4). 30. 28. setfillstyle(1.47.40. lineto(x+20. 21.31. 21.23. int y){ static char pica[] = {20.41. 11. line(x+11. 18.26. 24. lineto(x+40.0).27. 17.33."Pica"). lineto(x+22.36.26.32.36. 14. 25. RED).44.22.y+18.38.42.y+30.42.25.0).45. 19. settextstyle(SMALL_FONT.x+15.41. 15. 21.40. } void Icono11(int x. x+=5. 18.49.y+30).28.y+25). 28.34.46.y+10). 20. 23.44.36. lineto(x+25.y+45). int i.y+7).x+29. 18. 27.49. 26. 13. 21.x+10. 22.33.44. bar3d(x+22. setcolor(DARKGRAY). 24.42. lineto(x+37. 22. y+AltoIcono.23. settextstyle(SMALL_FONT. 16.49. 11.39. 23.y+18. settextjustify(CENTER_TEXT.y+35. HORIZ_DIR. 21. 27. lineto(x+43. 23.31. HORIZ_DIR. 22. 13. 21.y+32.47.y+13).40. 19.24. RED). line(x+10.29. 27. 12.35.42. 29.42.44. 12. 19. 17. 20.46. lineto(x+17.49. i+=2) putpixel(x+diamante[i].y+45).42.47.35.25. 15. y-=10. 15.32.y+30).33. 15.y+27). 23. line(x+15.50.35. 20. lineto(x+42. 17. 30.48. 26.28.41.46. 24. 14.x+22.22.25.37.41.y+10).48.21. 13. lineto(x+40.34. RED).x+15.38.42.outtextxy(x+AnchoIcono/2."Diamante").43.46. bar(x+15. 11. 24. y+AltoIcono.x+20. 22. 17. 20. 29. 18. 4). 28.39.43. 22.45.38.y+33).48. bar(x+9. y+pica[i+1].34. setfillstyle(SOLID_FILL. lineto(x+20. setcolor(WHITE). 21. 18. 16.y+25.

30. y+30.23.50.28.39.int y){ static char corazon[]={20. 13.32.42.21.35.28.34. 41.31. 20.38. 39.27. int y){ static char uva[]={ 37. 40.29.30. y+30. 45. 16. 46. settextstyle(SMALL_FONT.50.32.28.48. RED).28.21. DARKGRAY). floodfill(x+20. HORIZ_DIR. 23. 29.21. y+trebol[i+1]. TOP_TEXT). 38. 30. 30. 14. 48. y+corazon[i+1]. 4). 15. 29. 44.28.26.47.27. 39. 44.32. 22.26. setcolor(MAGENTA). 23. 18. 38.37. 37. 23.31.25.38. 11. 42.38. 13. 18.26. 18.31.50. 26.24.29.39. setcolor(MAGENTA). 20. 30. 19. 28.25.40.30. 12.50. 21.39. 23. } void Icono13(int x. 29. 37.44. 12.33. 27. 38. y+45. 13. 47. 18.33.31.48.38.32.32.24. 39.32. 16.24.30.33. 37. 21. 22. 47. 22.33. 22.30.27. 37. 30. floodfill(x+20.32. i<sizeof(trebol). 42.41."Tr‚bol").24. 30. 14.33.36.27.30.35.50.25.49. 22.42. 17. floodfill(x+20. i+=2) // putpixel(x+trebol[i]. i+=2) // putpixel(x+corazon[i]. 19. x+=5. 37.39.31. 41. 25. 43.32.27. 37. DARKGRAY). 11. 20. 39. 18. 17. 12.34.38.46. 17.26. 14.28.26.37. 17.29.38. 38. 25. 41.26. 29. 40. HORIZ_DIR. 25.29. 21.22. 17. y-=10.30. 40.35. 28. 14. 17. setfillstyle(SOLID_FILL. RED).32. 19.43. 39. 26. 40. 25.30. 24. 21. 15.30. 18. 38. } void Icono14(int x. 19.45. 26. 17.31. 24. settextjustify(CENTER_TEXT. 25. 46. settextjustify(CENTER_TEXT. 24.25.23. 25. 38.39.34.31. 4).23. 41. 22. 40.25. 41. 41.21. DARKGRAY).22. y+30. 21.26.47. 17. 24.39. 39. 11. 39. 23. 18. 18.41.35.24.46. y+AltoIcono.39.43. 39.31.41. x+=5.31. 39.28. //98 puntos int i.38. 22. 24.30.28. floodfill(x+20. 27.42.25.21. DARKGRAY).50. 11. DARKGRAY). 19.23. 40.35.34.37.28. 26. 21. 28.43. 29. 27. settextstyle(SMALL_FONT.45.30.30.29.29. 41. y+46.38.31. 23. 13.45. 15.31. 40. 11.27. 12. 23.32.30. 16.31. y+AltoIcono. 17.41. DARKGRAY).50.38.48. settextstyle(SMALL_FONT.35. TOP_TEXT).46.25. 28.33.33. 41. 23.29.21. 30.44. 43. 12. 26. 16. 19.39.21.45.37.31. 22.27. 24.25}. 22.30.34. 38. 24.47. 14. 23. 18.34. 21. 20.34.36.48.38. 17.36.44.24.37.23.39. 24.21. 20.30.31. 22. 30.30.22. 27.28.34.28. 21. 16. 18. 19. 24. 4). 21.29. 20. 28. 11. 39.42. 11.40.28. 15. 19.21. 41. 18.31. floodfill(x+20. 16. int i. 30. 38.22.21.32.26. 11.outtextxy(x+AnchoIcono/2. settextjustify(CENTER_TEXT. 37. 40. 30. 16. 19.setfillstyle(SOLID_FILL. 12. 18. 22. for(i=0.36. 38. 39. 19.21}.29.31.31.25.33. 15. y-=10.35.37. setfillstyle(SOLID_FILL.34.37. 14.46.31.50. RED).31.22.30.40.24.35 }.21. 23. 40.28.37.31. 13. 16. 11.25. 38. 23. 22. 22. i<sizeof(corazon). 37.outtextxy(x+AnchoIcono/2. 11. 40.40. 25."Corazón"). HORIZ_DIR. 19. 29.49. 12.27. 27. 87 . 23. DARKGRAY). } void Icono15(int x. 29.44. 38.43. 19. 20. 37.25. 23. 37.39.int y){ static char trebol[] ={20. for(i=0.29.22. 41.36. 19. 11.27.35. 27. 30. 19.39.33.32.21.32. TOP_TEXT).23. 41. 22. 18.32. 25.26.47. 40.36.28.39. 45.21.

16. 41. 20. 50.25. 48.32.12.30. 33. y+uva[i+1]+20. i<sizeof(palo).18. 40. setfillstyle(SOLID_FILL.14. int i.y+60. 45. floodfill(x+41. 50.37. 32.50.22. static char palo[] = { 28. circle(x+34. 8."Uva").17.29. MAGENTA). 10. y-=25. 28.40.35 }.48.16. 48. } void Icono16(int x. 39.28. 41.18.18. y+49. 47. floodfill(x+41.31.outtextxy(x+AnchoIcono/2.32. 19.25. MAGENTA). y+manzana[i+1]+20. 28. 31.16. TOP_TEXT). 38. 39.MAGENTA). 32.28.11. 12. 38.6).47. 42. 47.29.50.19. setfillstyle(SOLID_FILL. 28. 37.33.circle(x+40. floodfill(x+53. MAGENTA). 40.14.26.10. 10.31.10. 48. y+31. 35. i+=2) putpixel(x+manzana[i]+12. 30. 8.19. for(i=0.27. 41. circle(x+28.50. 25.26.43.11.29.13. 34. 36.50.27.32.19. 39.23. 50.50.20. 35."Manzana").28. 50.16.26. setfillstyle(SOLID_FILL. 46. 28. 14. 43.46.28. 29. 30. 37.37.6). 26. 34.50. 38. 28. 20.17.46. 50. 38. 18. floodfill(x+35. 15.10. x-=15. 37. 8. 29. 42. 41.20. BROWN).41.33. settextstyle(SMALL_FONT. for(i=0.16. i+=2) //45*2 = 90 putpixel(x+palo[i]+12.24.44. 38. 38. y+59. settextjustify(CENTER_TEXT. 28. 50.14. 28.22.19. 23.35. 48.33.25.20. 23.32.34.16.34. 30. 33.50. 30. HORIZ_DIR. 30. 27. 4).29.30.10.6).50 }. 37. 37. 8. i<sizeof(manzana).16. 11. 10.35.y+50.23.30. 42. 43.26. 8.43.y+50. 10. GREEN). 8.17. 40. 38. 27.24. 8. 28. 38. 26. MAGENTA).32.16.y+40.23.32. for(i=0. 30. 8. 38.16.25.22. 28. 44.41.21. 30. MAGENTA). 18.19. 27.45.28. 50. 24.48. 38. 40. 47.32.10. 37. 23. 9.50.15. RED). 41.27. 38.31. 39. y+39.50.21. 17. 9.25. 14. 24. 45.22 }.10. 17.20. 8. 41. 8.16.50. 26.29. 40. 49. 39. 50.50.29.18.6). 13.circle(x+40.47. i<sizeof(uva).21. 12. 21. 24. 9. 25. 40. 31. 42. 25.42. 32. 45. 29. 46.34. 30.40. 44.38. 27.14. 50. y+AltoIcono. int y){ static char naranja[]={ 37.29. setcolor(MAGENTA).6). 41. 30. y+palo[i+1]+20.33. 31.50. 33. 16. 44. 40.50.10. 45. 50.28. 41.50.28. int i.21.21.16.17. 26.45. 13.10. y+49. 21.14. floodfill(x+47.50.30. 49.14.49. y+52. 39. 24. 48.20. 39. floodfill(x+41.31.16. HORIZ_DIR.21. 30.28.10. 22. 33. int y){ static char manzana[] = {16. y+AltoIcono. 4). 36. 47. 88 . 41. 28.18. 37. LIGHTRED). y+39. 41. settextstyle(SMALL_FONT.36.34.setcolor(MAGENTA). 41.32.35.50. 40.32.outtextxy(x+AnchoIcono/2.25. 40.32. 41.38. int i. setcolor(MAGENTA). 29.50.25.50. 37.29.14. 37.6).18. 39.33. 28.13.26. 19.28.27. 50. 46. 8. 32. 31.12. 8.50. 38.32.28. 25.27.16.30.50.16.35.17.49. i+=2) putpixel(x+uva[i]+12. 8. GREEN).26. LIGHTRED).35. 40. 41.28. 46. x-=15.31.14. 37. floodfill(x+29.20.16. 8. } void Icono17(int x. 26.35. 22.y+40. 35.circle(x+52. 38.circle(x+46. 39.34. 8.19. 40.30.44. 36.10. 10. 30. 44. 39.31. 50.34. 30.y+40. 39.33.26. 40. GREEN).39. 34. 37. 50.27.34. 50. 30. 22. 43. 10. 35.30.33. 11. 34. 23.16.42. 40.39. 28.28. 37.15.22. 15. MAGENTA). floodfill(x+42.17. 8. 50.14.14.36. 9.50.31.32. 39.10. y+39.27. y-=25.31.30. 39. 43.50.

setfillstyle(SOLID_FILL. 53. 42.5).38. } void Icono19(int x.37.48. 43. TOP_TEXT). } void Icono20(int x.39.34. 5). TOP_TEXT). 40.y+45. 35. floodfill(x+45. YELLOW).5).29. 49.31. floodfill(x+40. 43.37. y+51.25.outtextxy(x+AnchoIcono/2. int y){ settextstyle(SMALL_FONT. 43.settextjustify(CENTER_TEXT.34. setfillstyle(SOLID_FILL. 42. y+AltoIcono.20. 42. setcolor(LIGHTGRAY). 42.47.52. TOP_TEXT).46. LIGHTRED).30. y+44. y+AltoIcono.2.YELLOW).29.31. } void Icono21(int x. y+20. 33. 43. 43."ã"). 47.5).30.33.31.outtextxy(x+AnchoIcono/2.y+45. circle(x+40. for(i=0. i+=2) putpixel(x+cereza[i]-3. 42. 45. HORIZ_DIR.y+50. setcolor(YELLOW). i<sizeof(cereza). 42. i<sizeof(naranja). y+cereza[i+1]+2. y-=20.25.41. setcolor(MAGENTA).18.26. y+naranja[i+1]. setfillstyle(SOLID_FILL. 50.38}.27. setfillstyle(SOLID_FILL. i+=2) putpixel(x+naranja[i]."Cereza"). 43. circle(x+39. 43.36. 44. 42. setcolor(YELLOW).29. LIGHTRED). 42.floodfill(x+41.outtextxy(x+AnchoIcono/2. 43.33.outtextxy(x+AnchoIcono/2.29.36. 43.31. 4). 43. HORIZ_DIR.50.30.42. y+AltoIcono. settextjustify(CENTER_TEXT. setcolor(MAGENTA). 34. HORIZ_DIR.34.49. 42.28.18).35. 39. fillellipse(x+24. 43."Banano"). setcolor(LIGHTRED). 46. 43.40.43. 43.34. 47.45.LIGHTRED).LIGHTGRAY). int y){ settextstyle(TRIPLEX_FONT. 38.29. 43. 45. int y){ static char cereza[] = { 42. y+AltoIcono. 37.43. 43. int y){ settextstyle(SMALL_FONT.33. 48.50. 51. 42. GREEN).31. LIGHTRED). settextstyle(SMALL_FONT.32.33. circle(x+50.y+45. 42. 4).2. 43. 42.33.36.36.28. CENTER_TEXT).30.52.35. YELLOW). 42. settextjustify(CENTER_TEXT.45. 36. 43.39. 43.36. x-=15. fillellipse(x+38. 42.48.44.51. setcolor(YELLOW). 50.32. TOP_TEXT). 43.34. 39."ã").29.36. 43. circle(x+30. 43. 43. 42. x-=10. settextstyle(SMALL_FONT. 46. 42. 43. 35. 42. 49. 37. y-=20. DARKGRAY). HORIZ_DIR. y+44.29. setcolor(DARKGRAY). 48. 4).35.32. setfillstyle(SOLID_FILL. 43.30.51. 43. 4). floodfill(x+51.34.y+60. for(int i=0.32. y+30. TOP_TEXT).2).30.33.49. 43.27. settextjustify(CENTER_TEXT. 36. 34.42. 42.37.y+26. x-=15.41. 42.2). fillellipse(x+41.40. 42. 42. 42.46. settextjustify(CENTER_TEXT. setfillstyle(SOLID_FILL. 40. HORIZ_DIR. 38.44.DARKGRAY).35.32.14).y+60. 42.32. outtextxy(x+25. 89 . 42. setcolor(MAGENTA).47.38. 42. floodfill(x+31. 43.31.26.37. GREEN). settextjustify(CENTER_TEXT. 41. y+59.y+41. 42. } void Icono18(int x. fillellipse(x+30. 42. 41. 51. 43.20)."Naranja"). setcolor(MAGENTA).35. 42. 52. GREEN). 43. y-=20. 52.37.35.

25. 30. 46.16. 31. 31.27. 34.20.16. 37.52. 30.16.4). 38. settextjustify(CENTER_TEXT. 33.26.17. int y){ static char fresa[] = 31. x+=5. 38.51. 28.outtextxy(x+AnchoIcono/2. 38.28. YELLOW). CENTER_TEXT).38. 43. 18.16. setfillstyle(SOLID_FILL. y+fresa[i+1]+12. 32.12. 24. 29. 28. 30. 46. 27.52.26.50.17. 24. 39. 39. floodfill(x+40. y+25.30. setfillstyle(SOLID_FILL. floodfill(x+30.27. 44.38. setcolor(YELLOW). 34.46. 19.32. 40.40. y+33. 29.21. 42.29.11.26. outtextxy(x+25. 24. i<sizeof(fresa). LIGHTRED).32.26. circle(x+20.34. 26. 18. 27. 1). static char cereza[]={30.46. for(i=0. 26. y-=18. y+AltoIcono.25. 40.27. 20.11.15).37. 34.42. int y){ settextstyle(SMALL_FONT. 24. 21.y+40. 35. setcolor(MAGENTA).36.24.25. 32.33.19.49.GREEN). floodfill(x+13. 35.12. 26. 25.45. 45. 43. 29. 24.14. 32. 27. y-=10. 20. 25. 46. y+25.16.29. 39. 23.22.52. settextjustify(CENTER_TEXT. 44.32. 37. 42. 34.42.16. static char palo[] = { 30. 19.10.36. 26. 30. 31. GREEN).25.25. LIGHTRED).27.26. RED). 19.4).26.30. RED).26.21. 18. circle(x+25. 18.27.26. 34. 30.25. 33.10. 21.51. 24. 18.16. outtextxy(x+AnchoIcono/2. 23.24.21. HORIZ_DIR.28. circle(x+25. 18. 30. 32.25.26. 28.40. 42. 29. 18. 38.17. 38. 20. setcolor(BLACK). } void Icono22(int x.28.16. circle(x+13. 20. y+AltoIcono. 38.29. 41.15. i<sizeof(palo).29.25. int i. 40. 35. floodfill(x+26. 18. 23.41.19.18.43. y+40. 28. 25.29. 22. 46.35.16.23."$"). 20.16. settextjustify(CENTER_TEXT.28.18. 29. y+40. 22. 30. LIGHTRED). 46. 22.16.48.52 }.46. 41.42.30. } void Icono23(int x.47.45.24. 32.27.16. 22.18. i+=2) //46*2 = 92 putpixel(x+palo[i]+9. 40.24."Moneda"). 36. 35.27.16.22.24.15.26.25. RED).25.32.28.31.39.33.36. 90 . 42. 46. 26.24. for(i=0.//138 puntos settextstyle(SMALL_FONT.13.52. 27. 32.20. 44.28. floodfill(x+20. 30. 22. 27. 22.42.34. 34.39. 20.27. 18. 34. 30. HORIZ_DIR.25. 22.29.47. 41. 30.24. y+25.24.29. y+palo[i+1]+12.29.48. 22. 20.y+45.14. 36. floodfill(x+25. 4).23.24.43. 25. 20. 36. 21.YELLOW). 20. 38. 32.31.30. 18. HORIZ_DIR. 41.22. i+=2) putpixel(x+fresa[i]+9.24.38. 23.16.34.46 }.36.27. 32.27.4).23.30.28. 42.y+40. 21.35. 44. 28. setfillstyle(SOLID_FILL.25. y+AltoIcono.15. floodfill(x+41. 30. 44.50.31. 25.10. 32.26.44.28.29. 32. 26.41.27. 33. setcolor(MAGENTA). 42. 37. 31.15. 23. 46. 44. 22. 18.19.28. settextstyle(TRIPLEX_FONT. y+25.27.outtextxy(x+AnchoIcono/2. GREEN). 4). 28. 43. 21. 45.setcolor(MAGENTA).26.49. y+45. 19.38.13. 26. { 24.20. 33. 26. circle(x+26.44.52.34.28.35.33. 46. 44. 21. setfillstyle(SOLID_FILL. 44. 38. RED). 27. 44. 20. y+40. 31.34. x-=15.28. 37. 20.17. 46. 39. 20."Cereza"). 36. TOP_TEXT). 18.16.13). 43.16. 20. 34.24.16.27.36. 20.52. 18. 44. setcolor(RED).26.37."Fresa"). 23. RED). TOP_TEXT).30.y+25.

x+18.16. 4).y+20).y+36). setfillstyle(SOLID_FILL.34.x+18.24. 26.y+49).19. line(x+20. 91 .x+22. fillellipse(x+18. 19. settextjustify(CENTER_TEXT.y+36). 17.3). floodfill(x+20.22. y-=10. line(x+18.y+36. line(x+28.2). y+45. 4).39. 4). i<80. 25.24.outtextxy(x+AnchoIcono/2.20.y+23. 23.y+49).25. GREEN).y+36).28.x+22.36. 24. int Y){ int r = 20.y+36). y+naranja[i+1]. 20.outtextxy(X+AnchoIcono/2. floodfill(x+17.outtextxy(x+AnchoIcono/2. TOP_TEXT). line(x+18. y+27. TOP_TEXT). HORIZ_DIR. line(x+22."Naranja").21. setcolor(MAGENTA). line(x+18. floodfill(x+20.17.32. y-=10. GREEN).36. settextstyle(SMALL_FONT.35. line(x+28.y+20.32.25. GREEN). 15. } void Icono25(int x. y-=10. y+cereza[i+1]. circle(x+20.25. 20.37 }.20.21. TOP_TEXT). settextstyle(SMALL_FONT. Color).x+28.y+36).22."OVNI").6.y+49). 16. 29.29.38.33. } void Icono26(int x. line(x+12. 4).y+49. Color). settextjustify(CENTER_TEXT.21.x+20.y+36. y.22. 28. GREEN).26. fillellipse(x+17. x+=5.y+27.y+36.16.x+12.x+12. GREEN).y+36.y+20).3. color. i+=2) putpixel(x+naranja[i]. Color).y+36. 27. 22. y+23. int y){// abajo int Color=DARKGRAY.33.37. static char naranja []={30. 21. setfillstyle(SOLID_FILL.x+18. line(x+12.y+36).37. int y){ // Arriba int Color=DARKGRAY. LIGHTRED). line(x+22. } void Icono27(int X. setcolor(MAGENTA). 27. GREEN)."Abajo"). HORIZ_DIR. y+AltoIcono. for(int i=0.y+20. x+=5.x+20. line(x+22. 26. settextjustify(CENTER_TEXT. settextjustify(CENTER_TEXT. 28. line(x+18. y+AltoIcono. for(int i=0. TOP_TEXT). line(x+20. floodfill(x+17.15. 20.y+36). floodfill(x+20. setcolor(MAGENTA). settextstyle(SMALL_FONT.x+18.17. y+45. line(x+22. setcolor(Color).y+36. } void Icono24(int x.10).31}.y+20).y+40.27. x+=5.y+49.24.y+49. setcolor(Color).34. Color). setfillstyle(SOLID_FILL.y+36. i<38.x+22. x.30.23. setfillstyle(SOLID_FILL.40. y+AltoIcono. setfillstyle(SOLID_FILL.y+20.18.x+28. 20. setcolor(LIGHTRED).YELLOW). Y+AltoIcono. 18. 26.35.y+40. HORIZ_DIR. setcolor(MAGENTA). HORIZ_DIR."Arriba").y+36.23.x+22. int y){ settextstyle(SMALL_FONT.y+36).outtextxy(x+AnchoIcono/2.23. 14. i+=2) //40*2 = 80 putpixel(x+cereza[i].

4). arc(x. HORIZ_DIR.y+15.y+10.x+5.11. setcolor(CYAN). 22.outtextxy(x+AnchoIcono/2. y+=15. 19.5. 357.y+20).3 ). line(x+26.2).y+15). 17.24. y+AltoIcono. TOP_TEXT). Y+=25.8.line(x+25. 2). setcolor(MAGENTA). 19. Y-4.10).23. settextjustify(CENTER_TEXT. color = random( 15 ). ++i ){ x = 2 + random( 50 .20.5. 4).y).13.5. settextjustify(CENTER_TEXT. arc(x+15.y.circle(x+24.5.16. y+=15.y+5.y+10."OR").270.y+10). settextstyle(SMALL_FONT.x+5.y+15). outtextxy(x+20. line(x.15."Vertical").arc(x+15.x+17. 30.x+23. 16.21.x+15.3 ). setcolor(YELLOW). 19. TOP_TEXT). fillellipse(X+10. y = 2 + random( 50 . Y-6.270. y+=15. 19. TOP_TEXT). Y-12. 19. int y){ //AND settextstyle(SMALL_FONT.y+10. getmaxcolor() ). 16. HORIZ_DIR. line(x. y+AltoIcono. 4). line(X-7. x+=10. x+=10. 4). 18. putpixel( X+x. 2. settextjustify(CENTER_TEXT.line(x. 24.5.5.for( int i=0 .x+5.y+20.y+20).y+15. 25.5. setcolor(LIGHTBLUE). settextjustify(CENTER_TEXT.19.y+5. Y-6.12. color ). setcolor(MAGENTA).line(x+5.y). line(X+7.5. X-10.y+20). 2).5. 19. 72. r. 27.90. line(x+5.5.x+5. 21. 18."NOT"). 19. int y){ //NOT settextstyle(SMALL_FONT. line(x+5. Y-12). line(x. CENTER_TEXT). } X+=25. Y-12. } void Icono32(int x.y+20).22.5. 16.6. 29. settextjustify(CENTER_TEXT.y+10).5. } void Icono30(int x. setcolor(MAGENTA). } void Icono29(int x.7. 4).outtextxy(x+AnchoIcono/2. 19.300.9.18.y).y+5).10).y+10). 17. y+AltoIcono.90.x+5. (r/3)+2). setcolor(MAGENTA).x+5.y.y. } void Icono31(int x. 26. 2.y+10. y+AltoIcono.y+5. Y-12).y+10. y+25.17. 23. int y){ settextstyle(SMALL_FONT."AND").7.x+30.y+20. Y+y.5. VERT_DIR. r.10. 19. 16. r/3). 19.10). Y. X+10.x+5. HORIZ_DIR. int y){ //OR settextstyle(SMALL_FONT.x+30. line(x+5. 19.y+5). line(x+5. TOP_TEXT). 92 .x+9. ellipse(X.line(x.y+20. setcolor(BROWN).outtextxy(x+AnchoIcono/2. 19. x+=10.outtextxy(x+AnchoIcono/2.5. fillellipse(X.y+10. fillellipse(X-10.line(x+5. int y){ static char Torre[] = { 16. 19. line(x. 28. setfillstyle( SOLID_FILL.y+10.line(x+25.x+9. 20. 190.x+15.25.line(x+23.5.y+10).x+30.y+15. 19. HORIZ_DIR.y.y+10.y+15). line(x+5. } void Icono28(int x.14. 19."Horizontal").x+15.y+5). i<500 .

int i. 32. for(int i=0.18. 29.52. 11. 19.64.outtextxy(x+AnchoIcono/2.50.9. 27.15. 23. 28. 30.47. 24. floodfill (x+24.11. 22. 17. 35.16. 18. 15.28. 35.38. 30.28.50. 30. 16.11. y+AltoIcono. 26. 17.31.43.31. 28. 28. 30.35.16.27.27.30. 4).64. 20. 19.7.32. 17. 19. HORIZ_DIR. 25.35. 18. 4). 30. 17. 18.30.y+15. 23.58. 29.32.56.27.9. 18.64.20.2. 18. 16. 23.DARKGRAY).36. 23.37. 14.17.25. 16.64.32.32.19. 23.44.14. 19. 30." Peón"). 23. 18.34. 16. 17.32.64.12.12.32. 26. 16. 16.outtextxy(x+AnchoIcono/2.10. 23. 17. 14.35. 16.64.40.41. 23. 16.57.10.18. 24. 11.26. 30.64. 29.32. 17. 35. 28.32.64. 29. 30.10.1 }. 20. 19. 27.39. 16. TOP_TEXT). 30. 20. 27.44.23. int y){ static char Reina[] = { 23. 27.28.36.29. 14. setfillstyle (SOLID_FILL. 17.32. 20.20.22. 23. 21. 35.y+Peon[i+1]. 14.49. 16.36.20. 28.31. TOP_TEXT). 27.35. 20.23. 30. 27. 32.40.23.32. 28.i+=2) 93 .18.31. 27. 30.40.21.48.64 }. 23. 23.21. 16. 28.27.33. 16. 27. 19. settextjustify(CENTER_TEXT.57.64. 29. 26.16. 27.29. HORIZ_DIR. 13.10.40. 12. int y){ static char Peon[]={ 21.60.21. 16. 16.58. setcolor(MAGENTA). 19. 30. 27.24.8. 18.29. 28. 16.y+20.19.64. 29. 15.24.26.39. 28. y+AltoIcono.42.11.51. 27.64. 14.42.30. 24.54.33. 30.18.i<sizeof(Peon).40. 30.15.26.23.49. 19. 27.25.37.15.4. 29.28.12.34. 19. 21.40.38.40. 19.2. 18.12.63. 17.64.64.22.i+=2) putpixel(x+Peon[i]. 28. 18.17. 31.40. 34.22.64.16.17.24. 27.32.12. 30.24.28.38. floodfill(x+25. 20.33. 26.38. 32. 27. 27. 32. 11.outtextxy(x+AnchoIcono/2. 35. 30. 22.11.43.32.26.7.64.63.59. 28. 21.64.21. 16. 29.64.64. 24. 35. 18. setcolor(MAGENTA). 23. LIGHTCYAN).62. 26.23.26.53.29.i<sizeof(Reina).51.2. 28. y+AltoIcono.39. 29.29. 31. 20.64. 28. 13.46. 18. 33. for(i=0. 19.47. 17. y+Torre[i+1]. 25. 27.16.17. 17.29. 23.26. 11. 27. HORIZ_DIR.54.64. 30. i<sizeof(Torre). 18. i+=2) putpixel(x+Torre[i]. 16. 23.10. 16. 33.27.37.60. } void Icono34(int x.32.52. 30.59. BLUE). 30.26. 26. 11.64.14.27. 11. 24. 18. 15. 17. 25.31. DARKGRAY).10. 16.45. 16. 23. 27. 18.10. 23.40.32. 22. 29. 34. 30. 29. 16.35.40. 27.40. 26. 27.40. 25. DARKGRAY).48.27.20. 30.6.64. 30.25.40. 31.19. 27.64.18.13. 26. 30.13.16.16.18.19. 29. 28.4. settextstyle(SMALL_FONT. 30.16. 32. 30. 28. 30.39. settextstyle(SMALL_FONT. 30. 16. 30.40.13.21. 19.30.1. 16. 32. 30. settextstyle(SMALL_FONT. 16.20. 16. 23.17. 30. 26.45.32.55. 22.36. 16.32. setfillstyle (SOLID_FILL.64. 32.55. 15.11.18.DARKGRAY)."Torre").64. 28.30.61. 16.25.1.40.4.40. 29.15.40.30.25}. 22.32. 12. y-=13. 27. 28.64.13. 30. 28. 27. 23.25.61.14. 30. 17. 35. 24. setcolor(MAGENTA). 20. 29. 27.62. 19. 18. } void Icono33(int x.3.56.11. 14.3. 30. 4). 16. 27.16.8.27.29. 28. 30.33.16. 17. 22. 35.31.34. TOP_TEXT).53. 21."REINA").37. for(int i=0. 21. 27. 28. 16. 16.22. 11.32. 25.40. 18.28. 29. 16. 15.11. 16. settextjustify(CENTER_TEXT. 14.40. 30. 30.10.22.24. 30. y+=10. 30.40. 27. 27.46. 16. 28.34. 16. 29.40.41. 30. 19. settextjustify(CENTER_TEXT.19.32. 31.3.14. 25.17.

0. 6. 3. 12. 18. 12.19. 14. 22.20. 14.14.15. 12.26.16.40.17. 3.17. 14.14.12. 14. 9. 30.18. 0.12. 7.14. 15.40. int i. 4.6. 4. 0. 0.31.30. 3. 15. 15."Caballo").13. 27.13.9. 15.11. 32.15. 30. 0. 15. 29. 17. 0. 7. 0. 14.16. 14. 15. 14. 8.32. 4.21.9. 7. 16.11. 0.12. 15. 0. 7. 4.17.18.19.12.40. 12.11.11.18.14.11.26.13. 8. 0. 4.13. 8.11. 15.12. 12.15.19.19. 7.10.11. 0. 0.10.7. 18. 12. 6. 0.28. 6. 4. 4.i<sizeof(Caballo). 12. 12.13.40.10. 5. 8. 12.15. 19. 9.16.12. 8. 0.22. 27.12. y+AltoIcono. 3.24.16.15.6. 4.33.14. 23. settextstyle(SMALL_FONT. 9. 17. 15. 29. 9.20. 27.19. 4. 4. 15. 0. int y){ static char LORO[] = { 4.12. 12.19. 15. 4. 27. 0.18. 2.20. 12.13.25. 24. 4.24.33.21.18.15. 5.14.14.18. 7. 15.13.20.13. 8.13.27.10. 7.21. 0. 4. LIGHTRED).12.21.21.12. 7. 9.20. 15. 7. 12.13.18.12.6. 4.y+Reina[i+1].10.40.14. 5.19.13. 4. 12. 9.14. 12.14. 15. 12. 8. 5.10.17.15. 0. 15. 0. 9. 12.18. 9. 8. 12. 9. 15. 12.13. 12.10. 29. 12.10. 27. 12. 0.37. 7. 7. 8.18.10. 4. 15. 12.12. 6.11. 15. 0.11.14.15.15.13.22.12. 12. 8.14. 8. 3. 26. 14.19.13.16. 14. 20.19. 9.17.19. 7. 4.15.15.putpixel(x+Reina[i]. 15.11. DARKGRAY). 9. 5.37. 4.19. 4. 12. 6. } void Icono35(int x.10.19.14. 4.16.12. 12. 14. 15. 5.16. setfillstyle (SOLID_FILL.10. 14.10.19.10. 6.17.18. 12. 0.y+Caballo[i+1]. 0. 29.18.36.18. 0.10.19.25.13. 14.15. 0. 4. 19.18. 7.21.15. 0.23.19. 15. 16.16.11. 4.8. 4. setfillstyle (SOLID_FILL. 12.14. 8.20. 5. 15.20. 0.17. 5.35. 28.40.19.15.11.28. 12.15. 16.16.21.20. 8.18.10.11.14. 30.14.19.10. 4. 32.10. 14. 6. 15. 15. 7. 0.11.16.12. 8. 27. 5.16.38.20.14.16.12. 9. 30. 30. 6.19. 31.10. 12. 5.34. 15.15.17. 3. 14. 30.16. 20. 12.22.16. 15. 4. 7.34. 7.12. 14.10. 12.10. 4.40.15.14. 4. 12. 12. 12. 5.11.outtextxy(x+AnchoIcono/2.10.17. 15. 9. 7. 5.12. 12. 6. 15.14. 30. 6.10.18. 6.10.19. 4. 0.16.11. 12. 8. 12. 5.23. 8. 8. 7. int y){ static char Caballo[] = {12.13.14.17. TOP_TEXT).12. 12.13. 0. 12. 0. 8.15. 15.20. 4.8. 28.11. 0. 12. 13.i+=2) putpixel(x+Caballo[i]. 9.9. 5. 8.13. 12. 0. 15.13. for(i=0. 13.36. 12.17.17. 9. 14.18. 17. 4.12. 12.19. 0. 5. 4. 4. 12. 0.17. 7.40.40. 5. 4. 27. 0. 7.40.14.12. 0. 12.19.11.20.13.17. 9.17. 15. 12.16. 4. 6. 12. 15.17.40. 7.11. 12.32.17. 12. 7.20.13.14. 27.12.15. 15.16.17. 9. 5.16. 9.5.20. 12.16. 5. 9. 19.19. 4.15. 13. 8. 26.17. 4).15. 15. 8.11. 15. 20. 0.15.16.10. 12.21.18.19.9. 0. 8. 8. 0. 7. 8.14. 6.39 }.21.11. 12. 14. setcolor(MAGENTA).17. 15. 0.14.11. 27.16. 6. 21. 0. 6.10. 18.10.17.19. 32.11.12.15.18.18. 14.16.12. 0.13. 17. 8. 12.14.11.12. 15.10.16.20.25.13.11. 0.21.16. 0. 12. 14. 0. 3.10. 4. 12.21. 0. 12. 9.7.11.11. 0. 0.11. 0.9.18.11. 0. DARKGRAY). 4. 0.19. 7.15.12.20. 0. 12. 7. 12. 15. 5. 0. 15. 0. HORIZ_DIR. 30.13. floodfill (x+23.13. 27.12.floodfill(x+25.14.12. 6. 6. 9. 17.14. 0. 9.16.29. 12.13.10.12. 15.20.17.20. 16. 0.13. 7. 9. 15. 8.18. 12.15. 9. 4.10. 6.10. 4. 4.13.40. 9. 6. 0. 14. 8. 15. 0.14.15.10. 9. 31. DARKGRAY).13. 7.20.20.13.17. 32. 7.15. DARKGRAY).15. 14.11. 0.14. 3.17.40.8. 0. 15. 12.17.35. 15.20. 30.18. 22. 15. 4.9.11.17.10. 0.23.21.15.11.14. 9. 17.24. 6.12.8. 3. 14.27. 15. 0.17. 4.38. 21. LIGHTMAGENTA).16. 4.20. 8.16.40. 8. 28. 0. 0.13. 4.13.12.39. 12.11.10.14. 15. 8. 4. 15. 32.18. 19. 8. 16. 12. 12. 4. 12. 9. 3.14. 15. 15.12. 13. 8. 12.17. 2.20. 6. 15.11.10. 8. 0. 4.11. 15.18. 18.19. 0.17.10.14. 25. 15. 15.20.40. 4.20. 12. 31. 7. 3. 7.12. 31. 25. 4. 15.16. 12.14. 8.18. 6.13. 12.18. 24.14. 4.40. 12. 9.20. 0. 15.12.15. 0.11.19.10. 6.14. 4.31.11. 23. 15.y+21.18.7.16. 4. 0. 15. 3. 8. 4.19.14. 15. 0. 9.15. 9. 0.10.7.11. settextjustify(CENTER_TEXT. 8.13.12. 94 .16.12. 12. 28. 32. 4.13.17. 8.10. 18.14. 12.14.12. 5. 6.18. 14. } void Icono36(int x. 4. 16. 7. 14. 5. 12. 6. 2. 12. 15. 14. 9. 30. 6. 7. 9.30.29. 12. 0.20.17. 0.15. 12. 9. 12.18.12. 9. 14. 9.19.16. 0. 0.12.13. 0. 8. 15.11.18.15.y+25. 19.

1. 1.22.23. 1. 12.23.21. 12. 12.21. 6. 4. 12. 1.10.30. 1. 12. 8.14. 4. 12.19. 6.36.17. 12.22.26.25. 1. 12. 12. 14.33.21.21. 12.34.25.19.11.17. 4. 12. 12.18.25. 1.28.35. 12.36.27.30.28.31.23. 1.24.26. 1.14.14. 1. 12.24.25.18. 12.23.36.26.21.30. 0.16.27.36.16.35.25.23.29.28. 1. 7. 1.15.16.34. 12.29. 12.26.10.23. 4.33. 12. 12. 1. 12.27.31.22. 1.16. 14. 1. 12.27.32.31.17. 12. 5.18. 0.25. 0.23.34.33. 0.31.36.15.31.27.24.24.10.23.25.34.33.24. 5.30.26. 12.33.26.29.29. 0. 12.28.28.26. 12.16.32.23.35.13. 12. 12.34. 4.28.27. 12.19.15. 1.35. 1. 12. 8.24.36. 4.10. 1. 1.19.35. 1. 12.11. 12. 6. 12.24. 12.27.35.14. 1.32.32.26. 12.26. 12.34. 1. 0.33.26. 9.22.30.10. 8.21. 1. 12.27.27.41.33.30.27.33. 12.32. 12. 9.24.19.26.27.12. 12.39.14.28.31.26. 12. 1.32.34.18.24. 12.23.22.24.20.26. 14.23.31. 4.23. 8.36.24. 12.23.23. 4. 1. 12.36. 4.21.22.22.15. 12. 6. 1.29. 0. 12.19. 0. 9. 0.20. 12.30. 12.36.13.34. 1.29.29. 1.12. 12.27. 12.32. 0.32.32. 12.27.25. 12. 5.28. 12.22.29.29. 14.26.24.24.28.33.28. 1. 1.29.35. 12.36.21. 1.30.29.21.35. 12.11.32.34.11.25.31. 12. 0. 12.43.28. 12.24. 1. 1.25. 0.36. 7. 0. 1. 1. 12.27.36.28.13.17. 12.12. 7. 12. 12. 12. 12.32.20.35.29. 12. 4.20. 12.23.23.16.32. 0. 1. 12.12.31.20.24. 1.34.23. 0. 1.15. 1.13. 12.32. 4.36.18.32. 1. 4. 4. 1.15.11. 7.12. 12.24.29.28.30. 1.36.16.25. 5.34. 12.35.30.28.24. 6.36.25.31. 14.36. 5.25.39. 0. 12.28. 8.13. 12.21.27.32.34. 4.23. 12.25. 14.18. 6.35.20.26. 0.33. 1.30.36. 12. 12.29. 4.22. 4. 1.35.20. 0. 12.26.38.32.35.25.22. 4. 6.32.13.35. 12. 1.10.12.24.45.26.32. 12. 1. 14. 12.35.32.32.21. 12.30. 12. 1. 12.12. 1.22.36. 1.15. 0.29.21. 12. 12.35.35.29.23.21.28. 12. 12.34. 12. 4. 12.19.42. 0.23.23.35. 12.35. 14.10.37. 0.25.22. 6.25. 12.31.24.31.22.31.30. 12.17.29. 1.34.22. 1. 0.33.22.18.34. 0.19. 4.21. 12. 1. 12.30.25.10. 12.33. 1.38. 0. 4.35.34. 12.35.22.22. 4.13. 8. 1.35. 0. 1. 4. 6. 5.24.27.18.16. 4. 12.31. 12. 0.26.33. 9.21.18. 1.37.26.21. 8.17. 1. 6. 12. 0. 12.26.33. 12. 6. 1.26.23.35.25.26.31.27. 0.24. 12. 1. 1. 0. 1.25.32. 14. 12. 8.36.28. 0. 4.23. 8.31.32.34.21.32. 1.17. 0. 12.21.31.16.25.24.33.20. 12.12.34.33.31. 9.12.32.31.26.35. 12. 8. 9.36.15.22.20.29. 1.29. 12. 5.12.25.25.30.27.30. 0.17. 12. 1.20.14.25.36. 5. 0.13.31.26. 12. 12.27.32. 12.18. 12. 12.35.22. 7. 12.21.31.19. 9.35.12.28. 12.22. 12.34.17. 4. 14.26.36.29. 12.33.24.29. 1. 1.28.34. 6.24.30.31.30. 4.27. 12. 12. 1. 0. 12.35.10.31. 12. 12.15. 7. 12. 1.27.19. 12. 0. 5.33.32.32. 12.25.34. 8.24. 12. 12. 9.27.36.25.33. 0.22. 12.15. 12.10. 1.35.28.20.19.30. 1.14.27.21.28. 12. 9.32. 1. 12.28.25. 12.32. 7.13.30.28.17. 0. 14. 4.32. 12.32.25.32.34. 12.14. 12.29.36. 0.24.32. 12. 1.30.27.31.36. 4. 0.28. 0. 1.22. 0.17. 12. 1.33. 1.15. 12.27.27.30.33. 14. 12. 12. 6.29.12.25.32.13.28.28. 4.13.20.24. 7.33. 0. 9.26.23.26. 5.26.27.22.24. 12.28. 6.26. 6. 12. 12. 7. 12. 12.29.22. 12. 6. 4. 4.25.28. 12.12.21.31.36.23.23. 0. 1. 9. 0.22.33.23.24.31.30.14.40.14. 12.27.23.27. 12. 12.24.23. 4.33. 4. 12. 6.27.22. 95 .15.29.36.29.27.30.23. 12. 12. 1.33.24.36.12. 12.28.23.34.12. 12. 1.31. 8.25.33. 4.21.25.37. 12. 14. 5. 0.28. 1.33.29.16.20.34.34.32. 1. 12.36. 12.31.21. 6.31. 0.29.34. 12. 5.22. 12.10.24. 12.36. 5.26.27. 1.34.33.34.21.20.28. 12.23.31.36.33.23. 1.32.27. 0.26.31.30.17.33.21.20. 6. 12.24. 9.30.35.32. 12. 8. 0. 1.30.32.27.35.23.33.19. 1. 0. 1.33.25. 12.36.24.24.31.29.21. 1. 14. 12. 12.18.14. 0.27. 1.30. 1. 6.32.26.23.11.30.24. 1.23.22.16.24. 9.29.15.32.29. 1.25.29. 6.35.28. 4.30. 12. 1. 4.13.17. 4. 0.36.24.21. 0.24. 12.30.23.36. 12. 1. 7.10. 1.25. 0. 12.22.14.34.22.26.21. 12.11. 1. 12. 0. 1.27. 0.29.11. 1.23.24.35.26.22. 1. 12.27. 12. 7.14.29.29. 12. 12. 12. 12. 1.30.18.30. 4.24. 1.31. 1. 6. 12. 12. 7.30.13.21. 12.20. 12. 12. 4. 1. 9.36.34.31. 12. 1.35.16.27. 8. 12. 7.44.29.34.11.11.22. 4.26.29. 12. 4. 1. 1.11.22.30.36.31.33.24.26.16.26. 1.25. 12.35. 1.33. 1. 12.26.25.36. 0.27. 9. 1.33.25. 0.21.16.15.33.19.30.21.33.33.34. 12.22.34.12.15.30.36.11.27. 12. 1.36. 0.28.37. 12. 12.35.29.31.14.37. 1. 12.22.26. 12.16. 0. 5. 0.28.34. 12. 1. 12. 12.25. 12.28.23.22.29.10.25. 12.34.31.26. 7.28.34.26. 0. 0. 12. 0.17.26. 12. 1. 12. 12.22.34.36.13. 12.28.29. 0.22.36.27.13. 8.24. 6.22. 12. 12.23.29. 12.35. 12.13.14.19. 12.34.17.28.32.32. 1.36.30. 12. 1.28. 4.18. 1. 1.23.36. 12. 12.26.35.19. 7. 0.17.31. 12. 1.11.25.19. 6.22. 1.10.11.18.37.28. 12.33.27.35.18.28. 12.36.30.11.28. 12. 1.18.27. 12. 12.28.23. 12. 12. 7.27.16.12.15.31. 1. 12. 12.35.33.29. 12. 1.36. 0.34.30.31.25.10.35.30.30. 1. 5.31.29. 4. 12.33.14.36. 12. 6. 1.25.31. 1.26.28.30. 12.

4. 12.12.15. 12.53.30.40.18.37. 0.37.42.51.39. 12.25. 8.39. 7. 8.42.20.37.33. 12.31.44. 12. 4. 4.16. 12.17.20.20. 8. 12. 96 .38.37.38. 8. 0. 12. 8. 12. 12. 1. 12.18.42.50.41. 12. 12. 12.40.41.12.49.42.39.39.43. 0.16.12. 4.38.21.24.23.40.45.25.51. 12.38.41.16.38.50.47.41.30. 12. HORIZ_DIR.25.37. 4. 0. 9.39.31. 8. 8.10.43.23. 0.25. 12.45.17. 12.59.42.24. 9.14. 0. 4.41. y+AltoIcono.34.41. 12. 12. 12. 12.27. 4.27.21.40. 12.41.29.34. 6.26.24.36.41.38.12. 12.24.14.13.38.53.53.53. 7.12.39. 12.38. 12.42.56.43.41. 12.40.38.42.39.36.37.37.37.12. 12.40.37.41.24.38. 4.42. 4.37.42. 12.40. 12. 12.40.41. 12. 8.40. 12. 12.30. 12.50.39.47.14.38.46. 12.40.12. 1.58. 0.12.44. 8. for(int i=0. 12.15. 12.18.33. y.26. 12.43.1.37. 4.39.42. 12.23.44.58.58. 4. 4.14.44. 12. 4. 8. 9.25. 8.12.23.48.42.41. 4.39.41.37.39.14.35.38.37. 12.39.42.19.20.41.42.22.43. 4.26.38.38. 12. 4.28. 0.42.37. 12.38. 4.13. 12.38. 12.34. 12.36.43.50.56. 12.12. 12.57. 12.26.40.37. 0. 4.50.41. 12. 12. 4. 12.58.23.36.21.57. 12.40.45.42. 0. 12.42. 12. 12.37.42. 8.46.41.39.21.41. 8. 8.44.38.40.41. 12. 0.45.39. 12.45.24.42. 4.18.29.38.40. 8.21.20. 4. 12.40.39.16.15.46. 12. 12. 0.46.23.20.35.43. 12. 12.38.i+=3) putpixel(LORO[i+1].11. 1.55. 12.40. 8. 12.42. 12. 12.55. 12.37.38. 12. 8. 8.25.41.44.40. 8.37. 12.45. 4.38.40.52.10.42. 8.39. 12. 12.41.16.51.31.22.43. 12.45.43.38. 12. 12.40.39.18.37.43.40. 12.25.43. setviewport(x. 12. 12.39.42. 12. 1. 12. 12.13. 8. 8.57.37. 12. 4).32.42.45.47.37.40.30. setcolor(MAGENTA). 4.13.19.39.40.54.43. 12. 12. 8.12. 12. 12. 12.52.15. 12.49.48.21.41.29.14. 12.55.43. LORO[i]).37.42.39. 4.37.44. 12.44.37. 4. 12.38.11.43. 0.48. 12.38.22.39.22. 12.42. 4.43. 4.35. 8.24. 12.20. 12.38. 12.44.46.40.52.26.41.10.40.21.40.41.39. 12.39. 8.32.33.40. settextjustify(CENTER_TEXT. settextstyle(SMALL_FONT.43. 12. 12. 12.26.56.19. 12. 12. 4.40.41.43.48. 4.46. 12.28.40.39.54.56.37.39.40.43. 12.41.40. 12. 4. 12. 12.54.51.42.39.12. 12.46.13.37.40. 8. 0.41.39.52. LORO[i+2].53.41.18. 0. 12. 12. 12.12. 12. 12. 12. 1.17.37.46.18.43.41.40.27.40.38. 12.12.40.19.40.12. 12.44.22. 12.17.39.41.40. 0.33. x+AnchoIcono.38.38.38.51.42.24.41.38. 12.22. 0.37.39.38. 4. 12.22. 12.49.52. 12.37.23. 4.42.50. 12. 12.37.47. 12.28.37."LORO").41.37.37. 0. 12. 0. 12.18. 12. 12.21. 4.14. 12.39. 12.22. 12. 4. 4. 12.18.18. 12.15. 12.38.21.41.41.16. 4.48. 12. 12.44.47.23. 12.54.37.53. 4.39. 8. 12. 12.38. 12.28. 12.30.52. 12.39. 4.52.51. 12. 12. 12. 12.42.37.42. 12.40. 12.23. 12.24. 12.39.40.37.35.51. 12. 12.40.38.45.18. 12.13.41.59.22.50.57. 8.23.37. 4. 12.38.12.51. 0.50.43.54. 4.52.38.47.26. 9.25.15. 12.37. 4.11.40. 4.22.42. 12. 7.43. 12.44.38. 12.41. 12.38.33.39.41. 12.41.38. 12. 4. 0.49.43.46. 12.52. 9. 12. 12.42.44.40. 4.40.39.42.39.50. 12.42.40.41.38. 12.27.47. 12.13.39.52.20.53}.41.36.16.41.41.41.43.25.47.17.43.38.37. 12.14. 4.41.30. 12.50.51.43.41.34.52.42.41.12.37.37. 4. 4.45.41.29.51. 12.41.17. 4.39.45.40. 12. 12.40. 12.11.40.51. 8.41. 12.39.13. 12.16.22.22. 4.37. 1.50.34.31.40. 8.27.37.22. 12. 12.49. 12. 12. 0.38.40.39.51. 12.37.17.15.23. 12. 12.48.27.31.53.17. 4.17. 12. y+AltoIcono.31.52. 12.50.38.19.50. 4. 12.37.39.40.45.18. 12.34. 12.41. 4.35.42.32. 4.51.43.23.26.33.36.39.42.11.42.26.22.38.38. 0. 4.42.45.22.12. 8.42. 12.43.37.i<sizeof(LORO). 12.39.38. 4.49.18. 12.35. 12.41. 8.19. 12.39.41.16. 1).52.17. 0.37. 8.55.17. 12.37. 8.42.38.39.16.15.50. 12.44.23. 0.38.41. 12.40. 12.11.43. 12. 12.49.39.50.42.34. 12.47. 12.36.43.45. 12. 12.40.20. 8.42. 12.38.43. 12.21. 12.18.39.19.24. 4.50.39.38.42.50.42. 12.21.16.22. 12. 4.37.42. 12.43. 12.45.20.24.14. outtextxy(x+AnchoIcono/2.12.35.37.38. 4.44. 12. 12.10. 12.49.41.48.18.38.51.20. 4.19.42.39.51.43.41. 12.47.19.49. 12. 8.24. 12. 12.20.38.23.29.28. 0. 12.49.38.51.39.38.39. 12.49. 12.17.19. 12. 12. 4. 12.16. 8.42.39.49.21.46.19.45.23.39. 12.41. TOP_TEXT).32.17. 12. 12. 12. 0.25.48. 12. 4. 8.15.37.46.51.16. 0.48.40. 12.40.39. 8. 12.38.44. 12.23.27. 12. 4. 0.39.39.12.44.17. 12.43.39.39.29. 12. 12. 12.37.32.19.38. 8.50. 12. 4.44. 12. 12.14. 0. 12.48. 12.42. 12.52. 8.40. 4.37.43.54.15.50.40. 4. 12.43.40. 12. 12.41. 4.42.40.40.17.38. 12.28.39.41.38.43.44.40.37. 12. 8.47.52.32. 12.44.27. 8. 4.40.38.42.39.

setviewport(0, 0, 639, 479, 1); //Pantalla completa
}
/************************************************************************** */
/* Funcion : MarcoVentana
*/
/* Objetivo : Dibujar un ReCuadro resaltado o undido.
*/
/************************************************************************** */
void MarcoVentana(int x1, int y1, int x2, int y2,
int ColorArribaIzquierda,
int ColorAbajoDerecha)
{
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
setcolor(ColorArribaIzquierda);
line(x1, y1, x1, y2);
line(x1, y1, x2, y1);
setcolor(ColorAbajoDerecha);
line(x2, y1, x2, y2);
line(x1, y2, x2, y2);
}
/************************************************************************** */
/* Funcion : Cursor
*/
/* Objetivo : Realiza recuadro, con una cadena centrada en su interior,
*/
/*
da a significar una de las opciones de un menú
*/
/************************************************************************** */
void Cursor(int x,int y, int pos, int Oprimido)
{
Icono[pos](x, y);
setlinestyle(SOLID_LINE, 0, NORM_WIDTH); setcolor(DARKGRAY);
moveto(x, y); lineto(x+AnchoIcono, y);
lineto(x+AnchoIcono, y+AltoIcono); lineto(x, y+AltoIcono); lineto(x, y);
if (!Oprimido) {
setcolor(DARKGRAY);
line(x+1, y+1, x+1, y+AltoIcono-1);
line(x+1, y+1, x+AnchoIcono-1, y+1);
setcolor(WHITE);
line(x+AnchoIcono-1, y+1, x+AnchoIcono-1,
line(x+1, y+AnchoIcono-1, x+AnchoIcono-1,
}
else {
setcolor(WHITE);
line(x+1, y+1, x+1, y+AltoIcono-1);
line(x+1, y+1, x+AnchoIcono-1, y+1);
setcolor(DARKGRAY);
line(x+AnchoIcono-1, y+1, x+AnchoIcono-1,
line(x+1, y+AnchoIcono-1, x+AnchoIcono-1,
}

y+AnchoIcono-1);
y+AnchoIcono-1);

y+AnchoIcono-1);
y+AnchoIcono-1);

}
/************************************************************************** */
/* Funcion : main
*/
/* Objetivo : El programa inicia siempre por la función principal
*/
/************************************************************************** */
void main(){
int Manejador = DETECT, Modo, i, PosXi=25, PosYi=20, Deltax=80, Deltay=70;
initgraph(&Manejador, &Modo, "c:\\tc\\bgi");
cleardevice();
setbkcolor(LIGHTGRAY);
MarcoVentana(2, 2, 637, 477, DARKGRAY, WHITE);
MarcoVentana(4, 4, 635, 475, WHITE, DARKGRAY);
int x=PosXi, y=PosYi;

97

for(i=0; i<MaxIco; i++){
Cursor(x, y, i, 0);
x+=Deltax;
if(x>=639-Deltax){
x=PosXi; y+=Deltay;
}
}
Cursor(PosXi, PosYi, 0, 1); //Se activa opción del "menú"
getch();
}

98

MANEJO DE CADENAS DE CARACTERES
1. DECLARACION DE CADENA COMO VECTOR DE CARACTERES
A diferencia de muchos otros lenguajes, el lenguaje C/C++, no trae un tipo
primitivo de datos para el manejo de variables de tipo cadena, sino que, estas,
deben ser definidas o como un vector de caracteres(char) o como un puntero a
caracter.
En la definición como vector, veamos el siguiente programa CADENAS1.CPP:
0.1 Se lee una variable, definida como vector, de cadena de caracteres por
teclado y luego se muestra en pantalla su valor, como si fuera un vector de
caracteres y como "cadena".
//CADENAS1.CPP
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
void main(){
const LargoCadena = 10;
char cadena[LargoCadena+1];
int longitud;
clrscr();
cout << "Digite una cadena, hasta de " << LargoCadena << " caracteres: ";
gets(cadena);
longitud = strlen(cadena);
cout << endl << endl;
for(int i = 0; i < longitud; i++)
cout << cadena[i];
cout << "\n\n" << cadena;
getch();
}
En el programa anterior se define una variable de tipo cadena como un vector
de caracteres, su abstracción es la siguiente, al iniciar la ejecución del
programa:
cadena
longitud LargoCadena
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
┌───┐
┌───┐















│10 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
└───┘
└───┘
0
1
2
3
4
5
6
7
8
9 10 11
Observe que la variable cadena se ha dimensionado con LargoCadena+1
posiciones, es decir 10+1=11 posiciones(bytes), debe tener siempre esto en
cuenta, ya que se debe considerar un terminador de nulo, '\0' adicional a la
cadena que se pretenda almacenar en la variable cadena.
Inicialmente se pide se digite una cadena hasta de 10 caracteres de largo,
supongamos que esa cadena es: Cali Valle, en memoria quedará así:

99

cadena
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬────┬───┐
│'C'│'a'│'l'│'i'│' '│'V'│'a'│'l'│'l'│'e'│'\0'│

└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴────┴───┘
0
1
2
3
4
5
6
7
8
9 10
11

longitud
┌───┐


└───┘

LargoCadena
┌───┐
│10 │
└───┘

Observe que en la posición, 10, es decir a continuación del último caracter
válido, se ha asignado el caracter nulo "automáticamente por la instrucción
gets(), de esta forma es que el compilador "sabrá" hasta donde llega la cadena
que se ha asignado a la variable. Se deben digitar solo hasta LargoCadena
caracteres, en este caso, si se digitan más, el programa tomará un rumbo
inesperado y puede llegar hasta a bloquearse( simule esta situación, previo
almacenaje del archivo en disco).
A continuación se invoca la función strlen() de él archivo a incluir
string.h, ella de regreso, retornará el largo de la cadena, para nuestro caso 9,
asignándoselo a la variable longitud, de la siguiente forma:
cadena
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬────┬───┐
│'C'│'a'│'l'│'i'│' '│'V'│'a'│'l'│'l'│'e'│'\0'│

└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴────┴───┘
0
1
2
3
4
5
6
7
8
9 10
11

longitud
┌───┐
│ 9 │
└───┘

LargoCadena
┌───┐
│10 │
└───┘

A continuación se recorre la variable cadena, como cualquier otro vector,
utilizando un indice, i, y la instrucción repetitiva for. El efecto neto es
mostrar cada caracter en pantalla. Igual efecto se consigue con la instrucción
cout << cadena, como puede confirmar ejecutando el programa.
0.2 El siguiente programa pide digitar una cadena de caracteres y luego esta es
presentada centrada en la pantalla dos filas más abajo.
//CADENAS3.CPP
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
void main(){
char cadena[80]; int longitud;
clrscr();
cout <<"Digite una cadena para luego centrarla en la pantalla: ";
gets(cadena);
cout << endl << endl;
for(longitud = (80 - strlen(cadena))/2; longitud > 0; longitud--)
cout << " ";
cout << cadena;
}
2.0 DECLARACION DE CADENA COMO UN PUNTERO A CARÁCTER
En este caso
por medio de un
almacenar, esto
mayor cuidado en

la declaración de la variable
puntero a caracter, sin darle
último puede ser la ventaja,
el código de programación como

cadena de
un límite
pero tiene
es siempre

caracteres se efectúa
máximo a la cadena a
el inconveniente del
cuando se trabaja con

100

punteros. Ejecute el siguiente programa CADENAS2. Recomendamos no trabajar de esta forma... Recuerde que si en C no trabaja con punteros no está utilizando las verdaderas posibilidades que ofrece el lenguaje. 101 .CPP y efectúele todos los cambios que se le ocurrá. es probable que hasta se le bloquee el computador.

no reservándole espacio adecuado para trabajo. puts(cadena). La variable cadena se ha definido como un puntero a caracter.h> void main(){ char *cadena. definida como puntero. puts(cadena). j. aux. clrscr(). } cout << "\"frase ordenada alfabéticamente\": \n" .1 Se lee una variable. cout << endl << endl. gets(cadena). cadena[j] = aux.CPP #include <iostream. cadena[i] = cadena[j]. clrscr().//puts escribe cadena y es la instrucción "compañera" de gets getch(). for(i=0. con el dimencionamiento adecuado. i++) for(j = i+1. es probable que este programa le funcione bien muchas veces.h> #include <stdio. j<strlen(cadena). cout << "Longitud cadena = " << strlen(cadena) << "\n\n". int i.2 El siguiente programa presenta. j++) if(cadena[i] > cadena[j]){ aux = cadena[i].h> void main(){ char *cadena. cout << "Digite una cadena de caracteres: ".h> #include <conio.CPP #include <iostream. i<strlen(cadena). gets(cadena). 102 . en especial cuando digita cadenas largas.h> #include <string. cout << "Digite una frase: ".h> #include <stdio. //CADENAS4. a partir de la lectura de una cadena de caracteres. su ordenamiento alfabético ascendentemente.h> #include <string. Los punteros se dejan exclusivamente para recibir parámetros en la definición de funciones. } 0. de cadena de caracteres por teclado y luego se muestra en pantalla su valor. //CADENAS2. Insistimos en no recomendar esta forma de trabajo.h> #include <conio. pero alguna vez le fallará.0. Las variables de cadena deben ser definidas como vectores de caracter. cout << cadena << endl.

} 103 .

(97-65). } return c.CPP #include #include #include #include #include <iostream. while(*s && *s!=' '){ *s = tolower(*s). cadena++.h> int longitud (char *cadena){ int c=0. s++.1 Ejemplo de funciones varias para manipular cadenas de caracteres. } } void CopiarCadena(char *cadena2. //Similar a la función strlen de string. cadena++. char *cadena1){//Copia cadena1 en cadena2 *cadena2 = *cadena1.h> <stdlib.h while (*cadena){ if (*cadena>=97 && *cadena<=122 ) // ASCII: a=97 z=122 A=65 *cadena = *cadena .h> /* NULL*/ <ctype. s++. } } void Apropiado(char *s){ while(*s){ *s = toupper(*s). cadena++. while(*cadena1){ cadena2++. } void AMayusculas(char *cadena){ //similar a strupr de string.h. //CADENAS5.h> <conio. } while(*s && *s==' ') s++. *cadena2 = *cadena1. } } void AMinusculas(char *cadena){ //similar a strlwr de string. 104 . La mayoría vienen incorporadas en el archivo a incluir string.30 PROGRAMAS DE APLICACIÓN 3.h while (*cadena){ if (*cadena>=65 && *cadena<=90 ) // ASCII: A=65 Z=90 a=97 *cadena = *cadena + (97-65).h while(*cadena){ c++. cadena1++.h> <stdio.

cadena2++. s2[80]. char *cadena1){ //esta función es similar a strcat de string. } void main(){ char c1. char *cadena1){//Similar a strcmp de string. //coloca terminador nulo a la cadena2 } int CompararCadenas(char *cadena2.*/ while(*cadena1 == *cadena2){ if( *cadena1 == NULL && *cadena2 == NULL) return 0. char carviejo. } return contador. /*de la primera diferencia. while(*cadena != NULL){ if (*cadena == caracter) c++. posicion++. } *cadena2 = '\0'.h int posicion=1. } int SustituirCaracterPorOtro(char *cadena. return posicion. } int ContarOcurrenciaCaracter(char *cadena. cadena1++. c2. } cadena++. } if (*cadena1-1 < *cadena2-1) posicion = -posicion. while(*cadena){ if (*cadena == carviejo){ *cadena = carnuevo. contador++. cadena++. *s1="Esto es una prueba". 105 . } return c. char caracter){ int c=0. //las cadenas son iguales cadena1++. cadena2++.h while (*cadena2) //Encuentra final de cadena2 cadena2++.} } void ConcatenarCadena(char *cadena2. while(*cadena1){ //añade contenido de cadena1 a cadena2 *cadena2 = *cadena1. char carnuevo){ int contador=0.

cout << "\n\nCopiado S1 en s2 = "<< s2. clrscr(). AMinusculas(s1). cout << "\n\nEn mayúsculas fijas es: " <<s1. getch(). gets(s1). AMayusculas(s1). clrscr(). cout << "\ni = "<< ContarOcurrenciaCaracter(s2. clrscr(). 'a'). getch(). Apropiado(s1).int pos. cout << "\n\nDigite otra cadena:". c1. 'i'). cout << "\n\n\nDigite frase para contarle las vocales:".2 El siguiente programa permite leer una cadena de caracteres. cout << "\nDigite un caracter de anterior frase: ". c2) ) cout << "\n" << s2. 'e'). } 3. cout << ": Tiene una longitud de " << longitud(s1) << " caracteres \n". pos = CompararCadenas(s2. cin >> c1. gets(s2). cout << "\n\nEJEMPLO DE COMPARACION DE CADENAS \n" << "Digite cadena:". cin >> c2. 'o'). cout << "\ne = "<< ContarOcurrenciaCaracter(s2. if ( pos > 0) cout << "\n\nCadena " << s1 << " es mayor alfabeticamente que " << s2. cout<<"\nDigite nuevo caracter para sustituir a: " << c1 << "\n". cout << "\no = "<< ContarOcurrenciaCaracter(s2. " de cadenas"). else if ( pos < 0) cout <<"\n\nCadena " << s1 << " es menor alfabeticamente que " << s2. else cout << "\n\nLas cadenas "<< s2 << " y " << s1 << " son iguales". s1). else cout << "El caracter digitado no se encontró en frase". cout << "\n\nEn forma Apropiada es: " <<s1. gets(s2). if ( SustituirCaracterPorOtro(s2. cout << "\na = "<< ContarOcurrenciaCaracter(s2. ConcatenarCadena(s2. getch().s1). cout << s1. cout << "\n\nConcatenado S2 con un mensaje = " << s2. cout << "\nu = "<< ContarOcurrenciaCaracter(s2. CopiarCadena(s2. 'u'). cout << "\n\nEn minúsculas fijas es: " <<s1. con un tamaño 106 .

break. analizando cada uno de ellos y obrando en consecuencia. if(LeerCadena(vector. if(car==27) return (0). case 13: if(pos<LargoCad) //CR: entrar Cadena[pos]=NULL. cout << "\n\nDigite otra cadena: ".//retrocede break.y). scanf ó cin.h> #include <string. } } while ((car != 13) && (car != 27)). 10)) 107 . //LEERCADE. case 27: Cadena[0]=NULL. //puede que le falle algún día cout << "\n\nCadena digitada: " << puntero.máximo permitido. cout <<(char)8.h> #include <conio. switch(car) { case 0: car = getch().h> int LeerCadena(char *Cadena. return (1). y sin utilizar las instrucción tradicionales de lectura para cadenas. } void main(){ char *puntero. //se debe "perder" es tecla de función cout <<(char)8. } break. int LargoCad) { char car.CPP #include <iostream. case 8: if(pos>0) { //BS: retroceso cout <<(char)32.//escribe blanco y retrocede pos--. Cadena[0]=NULL. pos++. x=wherex(). cout << "\n\nDigite una cadena: ".h> #include <ctype. else Cadena[LargoCad]=NULL. clrscr(). int pos=0. //ESC: Escape gotoxy(x. default: Cadena[pos]=car. break. Se efectúa lectura de caracter tras caracter. tales como: gets. do{ car = getche(). //HT: tabulador break. clreol(). 8). case 9: cout <<(char)8 <<(char)32 <<(char)8. y=wherey(). vector[80]. LeerCadena(puntero.

). Ver el programa Graph_IO. //avanza un caracter si es un signo 108 . numero=0. return numero.4 La siguiente función. float ASCIIaFloat(char *CadNumerica) { int punto=0.. if(*c=='+' || *c=='-'){ c++. getch(). Ver el programa Graph_IO. convierte una cadena de texto en un real.3e5 . Inicio=0. ASCIIaFloat. como en: 5. i>=Inicio. PosPunto=0.). i--){ numero = numero+(int)((CadALeer[i]-'0')*exp ). Menos=0.3 La siguiente función. int ASCIIaInt(char *CadALeer){ int pos. char *c. LargoCad++. float Real. } for(int i=pos. } 3. exp*=10. Signo=1. Exponente. ASCIIaInt. while(*c){ *c= *(c+1).cpp para su utilización. if(CadALeer[0]=='-' || CadALeer[0]=='+'){ Inicio++. c++. } if(Menos) numero = -numero. convierte una cadena de texto en un entero. if(*c=='-') Signo = -1. } } c=CadNumerica. Reemplaza a la función atof(. float exp=1.. LargoCad=0. else cout << "Se canceló la lectura con ESC". i=0. } 3. //de -32768 a 32767 pos=strlen(CadALeer)-1. if(CadALeer[0]=='-') Menos++. Precaución: No acepta el caracter e. siempre y cuando lo sea. siempre y cuando lo sea..cout << "\n\nCadena digitada" << vector.cpp para su utilización. Reemplaza a la función atoi(. while (*CadNumerica == ' '){ // Elimina espacios en blanco al inicio c=CadNumerica..

. Exponente=1. //Cuenta el número de caracteres en la cadena if(*c=='. gettextsettings(&AnteriorTexto). i++. else //No se digitó un punto decimal i=LargoCad-1. int x=10.return 0.//Suma valor numérico de parte decimal Exponente /=10.} while( (*c>='0' && *c<='9') || (*c=='. AltoCar. } if(*c){//No llegó al final de cadena numérica. } } Real *= Signo. int largo=80. int y=10. return 0. i. //Suma valor numérico de parte entera Exponente *= 10. fin=0. } if(PosPunto>0){ //Se digitó el punto decimal i=PosPunto+1. struct viewporttype Vista. int LeerCadena(char *CadALeer. Terminar=0.'){ punto++. if(punto>1){ cout <<'\a'. while(i>=0 && c[i]!='+' && c[i]!='-'){ Real += (c[i]-'0')*Exponente. int ColorTexto=BLUE. while(i<LargoCad){ Real += (c[i]-'0')*Exponente. } 3. getviewsettings(&Vista). LongCar. struct textsettingstype AnteriorTexto. hay error cout <<'\a'. L. char Tecla.5 La siguiente función se encarga de capturar una cadena en una posición de la pantalla en modo gráfico. } PosPunto=LargoCad-1.') ){ LargoCad++. if(PosPunto>0) //Se digitó el punto decimal i=PosPunto-1. return (Real). No es numérico. } c++. Real=0. Insertar=1. 109 .1. Exponente=0. int ColorFondo=WHITE) { int pos=0. } c=CadNumerica. i--.

settextstyle(DEFAULT_FONT. while(i>=pos){ CadALeer[i+1] = CadALeer[i]. case Esc: pos=fin=0. L = (Vista. // asignar el caracter if(!Insertar || pos==fin){ if(pos>=fin){ CadALeer[pos+1]=Nulo. // lee la tecla digitada if(Tecla) { // es tecla que genera un byte switch(Tecla){ case CtrlC: Terminar = 1. CadALeer[0] = Nulo. break. 1). fin++. break. Borra lo escrito break.x+LongCar*largo+1.x+LongCar*largo. } } else{ if(fin>=largo) cout<< "\a". i--.x) /LongCar-1. AltoCar= textheight("I"). } } pos++. i = pos. //Tecla tabulador. } else cout <<"\a"."_"). break.y-1. CadALeer[0] = Nulo. setfillstyle(SOLID_FILL. ColorFondo). outtextxy(x. case Tab: cout << '\a'. } fin++.// tecla de escape. else{ if(Tecla>=Espacio){ CadALeer[pos]=Tecla. if(largo>L) largo = L.right .y+AltoCar). case Retroceso: if (pos > 0) { pos--.y+AltoCar+1). bar(x.y+1. break. rectangle(x-1. //valores por defecto LongCar= textwidth("H"). // Simular el cursor do { Tecla = getch().y. } fin--. Que no haga nada case Entrar: Terminar=1. default: if(pos>=largo) cout<< "\a". } 110 . i++. HORIZ_DIR. //barra en que se escribe setcolor(ColorTexto). while(i<=fin){ CadALeer[i] = CadALeer[i+1]. else{ i = fin.

else{ if(pos >= fin){ fin++. //Modo se inserción else Insertar=1. if ( (pos < largo) && !Terminar) outtextxy(x+(pos*LongCar). } } } else{ // tecla de secuencia de ESC. } pos++. a medida que borra while(i<=fin){ CadALeer[i] = CadALeer[i+1]. case AltX: Terminar = 1. Que no haga nada case CtrlIzq: . CadALeer). } } bar(x.y. Tecla es igual a 0 en primer byte Tecla = getch(). while(CadALeer[fin-1]==Espacio){//Se eliminarán espacios blancos al final CadALeer[fin]=Nulo. //Alt+X aborta el programa case End : pos=fin. } else cout <<"\a". break. while(i<=fin){ CadALeer[i] = CadALeer[i+1]. i++. break. break.x+LongCar*largo+1. case Del: i = pos. CadALeer[fin+1]=Nulo. case Der: if(pos>=largo-1) cout<< "\a". case Izq: if (pos > 0) { pos--.else cout << '\a'.//pos queda en el mismo sitio. //Tecla Derecha. case CtrlDer: . i++. exit(0). case Ins : if(Insertar) Insertar=0. } while (!Terminar). break. } fin--.y+1. outtextxy(x. CadALeer[pos]=Espacio.y-1. } while(CadALeer[0]==Espacio){ //Se eliminarán espacios en blanco al inicio i = 0. 111 .x+LongCar*largo. default: cout<< "\a". y+1. //se corre el nulo fin--."_").y+AltoCar+1). //barra en que se escribe rectangle(x-1. } break. // lee el segundo byte switch (Tecla) { case Home: pos=0.y+AltoCar). break.

y+AltoCar). 2.charsize). Numere cada una de las ventanas en orden ascendente a medida que se van creando. //barra en que se escribe rectangle(x-1. y+1. AnteriorTexto.AnteriorTexto. settextjustify(AnteriorTexto.direction. CadALeer).} fin--.CPP como archivo a incluir.x+LongCar*largo. } bar(x. // retorna el largo de la cadena } PROGRAMA A REALIZAR COMO EJERCICIO 1.y+AltoCar+1). outtextxy(x.y-1.CPP. en su lugar emplee las funciones dadas en este capítulo.vert).horiz.H. El texto debe ser reescrito adecuadamente en cada ventana cuando se retire una ventana que lo estaba tapando. 112 . El texto que se digite en cada ventana debe poder ser actualizado a voluntad en el número de ventana que se desee.AnteriorTexto. las que le faltaren elabore el correspondiente algoritmo en lenguaje C y utilícelas.x+LongCar*largo+1. Cree un archivo a incluir dentro de su proyecto con ellas. En todos los proyectos a presentar en este curso no utilice la librería String. En el programa de las ventanas realizado en el capítulo sobre pilas y con la ayuda de la función LeerCadena presentada en este capítulo y en el programa IO_Graph.y.font. //Se reescribe sin espacios al inicio y final //Restaura las condiciones antes de antes de entrar a esta función settextstyle(AnteriorTexto. Efectúe los cambios necesarios para utilizar el programa IO_Graph. permita efectuar lectura de varias lineas en cada ventana. return fin.

H> #include <ConIO.CPP #include <IOStream. } Cad[largo] = '\0'. while(E){ Cad[largo] = (char) (E % 10 +48). } else{ if(E<0) E = -E. largo++. E = Entero. //signo menos largo++. EnteroASCII(Entero. cout << "Digite un número entero: ".H> int EnteroASCII(long Entero. Cad[1]='\0'.3. } 113 . //'0'= 48 en ASCII E /= 10. i--. j--){ aux = Cad[i]. cout << "Convertido a cadena = " << Cad. if(Entero<0){ while (i >= 0){ //Se inserta el signo menos Cad[i+1] = Cad[i]. i<largo/2. i++. char *Cad){//reemplaza a la función itoa //Retorna el largo de la cadena numérica long E. j=largo-1. if (E==0){ Cad[0]='0'. El siguiente programa permite convertir en número entero a cadena. char aux. int largo=0. } } return largo. int Entero. } i=largo. Cad). Cad[i] = Cad[j]. //NUMASCII. } void main(){ char Cad[20]. } Cad[0] = '-'. cin >> Entero. for(int i=0. Cad[j] = aux.

114 .

Consultar descripción del algoritmo en el libro "Estructura de Datos" de S. double PilaNum[Max]. char Sacar(char). //============================================================================ // Definición variables globales //============================================================================ char PilaChar[Max]. //============================================================================ // FUNCIONES PROPIAS DE LA EVALUACION DE UNA EXPRESION ALGEBRAICA //============================================================================ int PriorizarOperadores(char op1. int ConvertirInfijaAPostfija(char.h> #include <conio.h> #include <ctype.h> #include <stdio.h> #include <stdlib. char *).h> //============================================================================ // Definición de algunas constantes y MACROS //============================================================================ #define Max 20 #define Nulo '\0' #define ValorAbsoluto(x) ( (x>=0)? x : 0-x ) #define EsNumerico(x) ( ((x>='0' && x<='9') || x=='. //POLACA.h> #include <Cadenas. int PriorizarOperadores(char. *CimaNum = Nulo. Página 191 a la 196. double EvaluarPostfija(char *). //Observe que está sobrecargada void Meter(double *.*CimaChar= Nulo. 115 . En el siguiente programa se efectúa evaluación de expresión algebraica. Lipschutz. char). double). //Observe que está sobrecargada double Sacar(double *).h> #include <math.EVALUACIÓN EXPRESIÓN ALGEBRAICA 1. char). char op2){ if (op1 == '(' ) return 0. APLICACIÓN DE NOTACIÓN POLACA INVERSA La notación postfija también en conocida como notación polaca inversa. CPP //============================================================================ // Inclusión de archivos de librerías con los que se trabajará //============================================================================ #include <iostream.')? 1 : 0 ) #define EsOperador(op) ((op=='+'||op=='-' || op=='/' ||op=='*' ||op =='^')? 1:0) #define EsOtros(p) ( (p=='(' || p==')' || p==' ')? 1 : 0) #define CaracterValido(x) ( (EsNumerico(x) || EsOperador(x) ||EsOtros(x))? 1:0 ) //============================================================================ // Definición de prototipos DE FUNCIONES //============================================================================ void Meter(char *. a continuación presento programa que convierten una expresión en infija a postfija y posteriormente se efectúa la evaluación de esta última.

if( (op1 == '/') || (op1 == '*') ){ if (op2 == '^') return 0. } } //---------------------------------------------------------------------------void Meter(char *P. double item){ if (CimaNum == (P+Max-1)){ cout <<"\n\nDesbordamiento". } } //---------------------------------------------------------------------------void Meter(double *P. exit(1). 116 . if (CimaChar == P) // Era el último elemento CimaChar = Nulo. return item. char item){ if (CimaChar == (P+Max-1)){ cout <<"\n\nDesbordamiento\a". /*Inicializa PilaNum*/ else CimaNum++. while(!kbhit()). /*Inicializa PilaChar*/ else CimaChar++. if ((op1 == '+') || (op1 == '-') || (op1 == '_') ){ if ((op2 == '^') || (op2 == '/') || (op2 == '*')) return 0. } if (op1 == '_') //menos unario después de paréntesis return 1. *CimaChar = item. else CimaChar--. if (CimaChar) { item = *CimaChar. getch(). if ((op2 == '+') || (op2 == '-') || (op2 == '_') ) return 1. } else { if (CimaChar == Nulo) CimaChar = PilaChar. } else { if (CimaNum == Nulo) CimaNum = PilaNum. } } //---------------------------------------------------------------------------char Sacar(char *P){ char item. exit(1).if (op1 == '^') return 1. *CimaNum = item. if ((op2=='/') || (op2=='*') || (op2=='+') || (op2=='-') || (op2=='_') ) return 1.

Punto=0. *Infija)){ //Si el operador en PilaChar es mayor o igual en presedencia Op[0] = Sacar(PilaChar). } return item. while(*Infija){ if(!CaracterValido(*Infija)) return 0. Op ). ""). //solucionar casos como: -(-3.} return. ConcatenarCadenas(Postfija. } else if (EsOperador(*Infija)){ if (!ParDer){ while( PriorizarOperadores(*CimaChar. ConcatenarCadenas(Postfija.//se concatena con Postfija 117 . '(').') ConcatenarCadenas(Postfija. ConcatenarCadenas(Postfija. if (CimaNum) { item = *CimaNum. con memos unario CimaChar= Nulo. AsignarCadena(Postfija. } else{ if(Digito) { if( *Infija==' ' && EsNumerico( *(Infija+1) ) ) return 0. Digito=1. ")"). no es un # válido Punto++. Op[0] = Infija[0]. Digito=0. "0"). " "). //ya hay un punto. ConcatenarCadenas(Infija. } //---------------------------------------------------------------------------int ConvertirInfijaAPostfija(char *Infija. ParDer=1. if (EsNumerico(*Infija)){ if(*Infija=='. if (CimaNum == P) /* Era el último elemento*/ CimaNum = Nulo. Op). //para saber si un número tiene más de un punto int ParDer=0.'){ if(Punto) return 0. } if (*Infija == '('){ Meter(PilaChar. //saber si el anterior(es) ha sido numérico(incluye punto) int Punto=0. char *Postfija){ char *Op=" \x0". // cuenta solo el primer punto } if(!Digito && *Infija=='. else CimaNum--. '('). } //---------------------------------------------------------------------------double Sacar(double *P){ double item. int Digito=0. Meter(PilaChar.

a = Sacar(PilaNum). a+b). atof(Numero)). ConcatenarCadenas(Postfija. } Meter(PilaChar. } }//if } p++. pow(a. case '-': Meter(PilaNum. break. while (EsNumerico(*p)){ aux[0] = *p.por _ *Infija = '_'. } else if (*Infija == ')') while ( (*Op=Sacar(PilaChar)) != '(' ){ ConcatenarCadenas(Postfija. } else{ if(EsOperador(*p) ){ b = Sacar(PilaNum). Nulo). 118 . b. while (*p){ if(EsNumerico(*p)){ AsignarCadena(Numero. Meter(PilaNum. " "). break. p++. case '*': Meter(PilaNum. a/b). //Mete en PilaNum el valor numérico } else{ if(*p=='_'){ // operador monario después de un paréntesis en infija a = Sacar(PilaNum). } } else if(*Infija=='-'){ //se cambia . aux). break.ConcatenarCadenas(Postfija. } Meter(PilaNum. " "). *Infija). a-b). no lo borre Numero[80]="\0". switch(*p){ case '^': Meter(PilaNum. Op). }//while return 1. CimaNum = Nulo. } //---------------------------------------------------------------------------double EvaluarPostfija(char *p){ double a. char *aux=" \x0". a*b). case '+': Meter(PilaNum. } }//if-else Infija++.b)). // ojo con el espacio en blanco. // '_' simbolizará el menos unario ParDer=0. break. ConcatenarCadenas(Numero. -a). case '/': Meter(PilaNum. break.

/ * ^ ").}//if-else }//while return(Sacar(PilaNum)). puts("Digite expresión algebraica en Infija: "). }//Fin main() //----------------------------------------------------------------------------- 119 . puts("Puede dejar espacios en blanco entre operandos y operador\n"). Postfija[Max]. cout <<"\n\nResultado = " << EvaluarPostfija(Postfija).1 digite como 2^(-1. puts("Los operadores pueden ser + . while(!kbhit()). if(ConvertirInfijaAPostfija(Infija.1)" ). puts("NOTA: los menos unarios serán convertidos al caracter _"). puts(Postfija). gets(Infija). clrscr(). puts(" 2 ^ -1. } //---------------------------------------------------------------------------void main(){ char Infija[Max].Postfija) ){ cout <<"\nExpresión correspondiente en Postfija: ". puts("En expresiones como: 2 ^ -1 digite como 2^(-1)"). } else puts("\nError en expresión Infija").

. Inicie el trabajo recodificando para expresiones del tipo y=f(x) y posteriormente. 120 .). 2.CPP diseñe una pequeña hoja de cálculo electrónico. Con la ayuda del programa MATRIZEL. Con la ayuda de POLACA..CPP y con POLACA. este programa le será de mucha utilidad en la asignatura de Método Numéricos que cursará posteriormente.CPP de este capítulo. amplíe a varias variables. debe el programa permitir digitar una expresión algebraica del tipo y = F(x) y a continuación aparecer la correspondiente gráfica en pantalla. 3. por ejemplo: y = f(x.PROGRAMAS A REALIZAR COMO EJERCICIO 1.CPP como herramienta. permita que se pueda digitar una expresión algebraica con variables.. Utilizando el programa POLACA.y.

char CarValidos[10]. void ObtenerOperadorNOT(int *Valor).h 121 . int *Operando1. int CompararCadenas(char *cadena1.EXPRESIÓN EN LÓGICA PROPOSICIONAL #include #include #include #include <IOStream. int ASCIIaInt(char *CadALeer).H> //=============================================================================/ /Definición de prototipos de todas las funciones utilizadas char AMayuscula(char c). char *CaracteresValidos). char *cadena1). void ObtenerOperadorAND(int *Valor). //Función sobrecargada void AnalizarExpresionLogica(int *Valor). int LongitudCadena(char *cadena). } //--------------------------------------------------------------------------char AMinuscula(char c){ if(c>=65 && c<=90) c += (97-65). void AsignarCadena(char *cadena2. //============================================================================= char AMayuscula(char c){ if(c>=97 && c<=122) c -= (97-65). return c. void MostrarNumeroError(int NumError). void EsperarTecla().H> <StdLib. char *cadena2). int ObtenerSimbolo(). char *Pos. char Simbolo[80]. void main(). void DeterminarOperador(char Operador. int EstaEn(char Caracter. void ObtenerParentesisIzquierdo(int *Valor). void AMinusculas(char *c). int ObtenerValorPrimitivo(int *Valor). void LeerLeyesDeDeMorgan(). void ObtenerOperadorOR(int *Valor). //=============================================================================/ /DEFINICION DE VARIABLES GLOBALES: char Expresion[80]. void TransformarExpresionLogica(). return c. int *Operando2). //-----------------------------------------------------------------------------void AnalizarExpresionLogica(). char AMinuscula(char c).H> <StdIO. } //--------------------------------------------------------------------------//esta funcion reemplaza a strlwr de la librer¡a string.H> <ConIo.

Menos=0. return 0. } //--------------------------------------------------------------------------/* Funcion : int ASCIIaInt */ /* Objetivo : Esta funcion convierte una cadena de texto en un entero.) */ //--------------------------------------------------------------------------int ASCIIaInt(char *CadALeer){ int pos. } //--------------------------------------------------------------------------int EstaEn(char Caracter. */ /* siempre y cuando lo sea. //de -32768 a 32767 float exp=1.h void AsignarCadena(char *cadena2. //No encontrado el caracter buscado } //--------------------------------------------------------------------------int LongitudCadena(char *cadena){//Similar a la funcion strlen de string. exp*=10.void AMinusculas(char *c){ while(*c){ *c = AMinuscula(*c).h int c=0. i>=Inicio. i--){ numero = numero+(int)((CadALeer[i]-'0')*exp ). */ /* Reemplaza a la funcion atoi(. if(getch()==0) getch(). c++. numero=0.. if(CadALeer[0]=='-') Menos++.. // Encontrado el caracter buscado else CaracteresValidos++. } for(int i=pos. return c. char *cadena1){ while(*cadena1){ 122 . } } //--------------------------------------------------------------------------void EsperarTecla(){ cout << "\n\n\nDigite cualquier tecla para seguir: ". while(*cadena++) c++. pos=LongitudCadena(CadALeer)-1. char *CaracteresValidos){ while(*CaracteresValidos) if(Caracter == *CaracteresValidos) return 1. if(CadALeer[0]=='-' || CadALeer[0]=='+'){ Inicio++. Inicio=0. } if(Menos) numero = -numero. return numero. } //--------------------------------------------------------------------------//La siguiente funcion reemplaza a strcpy del archivo a incluir string.

} //============================================================================= void AnalizarExpresionLogica(){ //Funcion sobrecargada int Valor. switch(Valor){ case 0 : cout << "Falso\n". if(! *Simbolo ) MostrarNumeroError(2). gets (Expresion). char *cadena2) { int pos=1. //Siempre debe ser NULL lo que asigne aqu¡ } //--------------------------------------------------------------------------int CompararCadenas(char *cadena1. case 'd': cout << "Desconocido\n". break.*cadena2 = *cadena1. if(*Expresion){ AMinusculas(Expresion). cout << "Separe con espacios en blanco: ". Por ejemplo: 1 & (d | 1) \n". cadena1++. AsignarCadena(CarValidos. cout << "Solo se pueden utilizar paréntesis redondos(). return pos. clrscr(). break. else 123 . cadena1++. AnalizarExpresionLogica(&Valor). } } //--------------------------------------------------------------------------void AnalizarExpresionLogica(int *Valor){ //Funcion sobrecargada ObtenerSimbolo(). Pos = Expresion. while(*cadena1==*cadena2) { if(*cadena1==NULL && *cadena2==NULL) return 0. para agrupar\n". cadena2++. cadena2++. cout << "\nEl resultado es: ". } if(*cadena1<*cadena2) pos = -pos. pos++. case 1 : cout << "Verdad\n". cout << "\ny constantes: 1 0 d \n\n". "()|&!"). break. cout << "Digite expresion logica. } *cadena2 = *cadena1. cout << "Puede digitar operadores: & | !". cout << Expresion << endl. } EsperarTecla().

DeterminarOperador(op. ObtenerSimbolo(). "Par‚ntesis desequilibrado". DeterminarOperador(op. int Mantiene. } //--------------------------------------------------------------------------void ObtenerOperadorOR(int *Valor){ char op. ObtenerOperadorOR(Valor). Valor. &Mantiene). cout << MensajeError[NumError] << endl. if( *Simbolo != ')') MostrarNumeroError(1). } //--------------------------------------------------------------------------void MostrarNumeroError(int NumError){ static char *MensajeError[]={"Error de sintasis". } ObtenerParentesisIzquierdo(Valor). 124 . op = 0. "Ninguna Expresion presente" }. } } //--------------------------------------------------------------------------void ObtenerOperadorAND(int *Valor){ char op. ObtenerOperadorNOT(&Mantiene). Valor. ObtenerSimbolo(). &Mantiene). ObtenerOperadorNOT(Valor). ObtenerOperadorAND(&Mantiene). while( (op = *Simbolo) == '|') { ObtenerSimbolo(). Valor. if(op) DeterminarOperador(op.ObtenerOperadorOR(Valor). } } //--------------------------------------------------------------------------void ObtenerOperadorNOT(int *Valor){ char op. while( (op = *Simbolo) == '&') { ObtenerSimbolo(). } //--------------------------------------------------------------------------void ObtenerParentesisIzquierdo(int *Valor){ if( *Simbolo == '(') { ObtenerSimbolo(). if( *Simbolo == '!') { op = '!'. ObtenerOperadorAND(Valor). Valor). int Mantiene.

} MostrarNumeroError(0). } } //--------------------------------------------------------------------------void LeerLeyesDeDeMorgan(){ AsignarCadena(CarValidos. clrscr(). cout << " no (P y Q) => no P o no Q \n". "()"). break. cout << "Las reglas de De Morgan son : \n". else *Operando1 = 'd'. int *Operando1. 125 . } //--------------------------------------------------------------------------int ObtenerValorPrimitivo(int *Valor){ int i. break. case '!': if(*Operando1 != 'd') *Operando1 = !*Operando1. return ObtenerSimbolo(). } if(*Operando1 == 'd' && *Operando2 == 0) *Operando1 = 0. return. //Error en sintaxis de expresion } //--------------------------------------------------------------------------void DeterminarOperador(char Operador. "01d") ){ if( *Simbolo == 'd') *Valor = 'd'. else *Operando1 = 'd'. case '|': if(*Operando1 != 'd' && *Operando2 != 'd'){ *Operando1 = *Operando1 || *Operando2. else *Valor = ASCIIaInt(Simbolo).} else ObtenerValorPrimitivo(Valor). return. else if(*Operando1 == 0 && *Operando2 == 'd') *Operando1 = 0. cout << " no (P o Q) => no P y no Q \n". } if(*Operando1 == 1 || *Operando2 == 1) *Operando1 = 1. break. int *Operando2){ switch(Operador){ case '&': if(*Operando1 != 'd' && *Operando2 != 'd'){ *Operando1 = *Operando1 && *Operando2. else *Operando1 = 'd'. if( EstaEn(*Simbolo.

"no") ){ ObtenerSimbolo(). AsignarCadena(q. q[80]. "no") ){ ObtenerSimbolo(). } } //Teoremas de De Morgan son : \n". return. "y") ) EsY = 1. AsignarCadena(p. TransformarExpresionLogica(). ObtenerSimbolo(). // se reinicializa ObtenerSimbolo(). } } //--------------------------------------------------------------------------void TransformarExpresionLogica(){ char p[80]. if(!CompararCadenas(Simbolo. Simbolo). "no") ){ ObtenerSimbolo(). //Teoremas de De Morgan en forma inversa : \n". if(!CompararCadenas(Simbolo. AsignarCadena(p. cout << Expresion << endl. // ~ (P y Q) => ~ P o ~ Q // ~ (P o Q) => ~ P y ~ Q Pos = Expresion. ObtenerSimbolo(). Simbolo). s[4]. // ~ P o ~ Q => ~ (P y Q) // ~ P y ~ Q => ~ (P o Q) Pos = Expresion. "y"). cout << "\n\nno (" << (char)AMayuscula(p[0]) << " " << s << " " << (char)AMayuscula(q[0]) << ")". if(*Expresion){ AMinusculas(Expresion). if(!CompararCadenas(Simbolo. "y") ) EsY = 1. if(!CompararCadenas(Simbolo. Simbolo). else EsY = 0. "o"). ObtenerSimbolo(). if(EsY) AsignarCadena(s. else 126 . ObtenerSimbolo(). EsY. else AsignarCadena(s. EsperarTecla(). gets(Expresion). Pos = Expresion. if(*Simbolo=='(') { ObtenerSimbolo(). if(!CompararCadenas(Simbolo.cout << "Digite una de las cuatro expresiones mostradas antes \n".

} //Avanza caracteres hasta encontrar un espacio o paréntesis. p = Simbolo. Analizar expresion logica \n". p++. CarValidos) ) { *p = *Pos. return 0. p++. cout << "Esc. *p = '\0'. 127 . return. //Salta espacios en blanco al inicio if(*Pos == '\0') { // es el final de la entrada *p++ = '\0'. } } } Pos = Expresion. return 0. if(*Simbolo. Verificar leyes de De Morgan \n". return.EsY = 0. ObtenerSimbolo(). cout << " 1. do{ clrscr(). Pos++. ObtenerSimbolo(). else AsignarCadena(s. return 1. } *p = '\0'. Pos++. cout << "\n\nno " << (char)AMayuscula(p[0]) << " " << s << " no " << (char)AMayuscula(q[0]). AsignarCadena(q. } if(EstaEn(*Pos. } //--------------------------------------------------------------------------void main(){ char opcion. ")") { //Es una expresion v lida de De Morgan if(EsY) AsignarCadena(s. // determinando una palabra while(*Pos != ' ' && !EstaEn(*Pos. Simbolo). para terminar el programa \n". "y"). // Se reinicializa cout << "\n\nTautolog¡a no implementada o mal escrita \a\a". } //--------------------------------------------------------------------------int ObtenerSimbolo(){ char *p. "o"). CarValidos) ) { *p = *Pos. while(*Pos==' ') Pos++. cout << " 2.

break. switch(opcion){ case '1': AnalizarExpresionLogica(). } //============================================================================= 128 . case '2': LeerLeyesDeDeMorgan(). break.opcion = getch(). } }while(opcion != 27).

Izq=75. CtrlDer=116. No. PosMenor. int N. int i. podrá observar una comparación gráfica entre los algoritmos de ordenamiento: Merge Sort con recursión. End=79.H> /****************************************************************************/ //Prototipos de funciones principales void MergeSort(int *Vector. MergeSort(Vector. 2. k++){ Vector[k] = (b[i]<b[j])? b[i++]:b[j--]. //Si lo aumenta de 314. int N) { int j.h> #include <StrStream.H> #include<ConIO. j). for(k = Izq. void GraficarValores(int *Datos. k.H> #include <StdLib. EL PROGRAMA /****************************************************************************/ #include<Graphics.h> #include <DOS. int N=0. Medio. CtrlIzq=115. int PosB. int Der). for(j = Medio. int Aux. 129 . //*************************************************************************** void MergeSort (int *Vector. j < Der. int i. int N). /****************************************************************************/ const Max = 312. Sorteo por Selección Recursiva. for(i = Medio+1. i--) b[i-1] = Vector[i-1]. Del=83. void Burbuja(int *Vector. Tab=9. int Izq.h> #include <Time. int Der). void QuickSort(int *Vector. i>Izq. const Home=71.COMPARACIÓN DE ORDENAMIENTOS 1. QuickSort con recursión y el tradicional y pésimo de Burbuja en forma iterativa. int b[Max]. k <= Der. CtrlC=3. int Der){ int i. la escala de las barras no queda bien. N. int Retardo=0). k. int Izq. INTRODUCCIÓN En el siguiente programa. AltX=45. int Izq. int N). Esc=27. int PosA. Retroceso=8. Der). Las versiones iterativos de los mismos degen trabajar más rápido que los presentados en este programa. Der=77. Lo anterior no quiere decir que los algoritmos recursivos sean más rápidos. } } } /****************************************************************************/ void SorteoPorSeleccionRecursiva (int *Vector. GraficarValores(Vector. Nulo='\0'. j. Espacio=32. if(Der>Izq){ Medio = (Der+Izq) >> 1. Medio+1. Ins=82. j++) b[Der+Medio-j] = Vector[j+1]. const Entrar=13. Izq. void SorteoPorSeleccionRecursiva(int *Vector. Medio). //Tama¤o del vector. todo lo contrario. MergeSort(Vector.

Vector[j+1] = Aux. j++) if(Vector[j] > Vector[j+1]){ Aux = Vector[j]. N. i). } } while(izq < der). i<N-1. j+1). j. Vector[j] = Vector[j+1]. Vector[der] = aux. Aux = Vector[PosMenor]. PosMenor. Vector[izq] = Vector[der]. der=Der. //Clasificación r pida int Izq. do{ while (Vector[izq] < pivote) izq++. aux. der). for(j=i+1. Der). N. GraficarValores(Vector. for(i=0. while (pivote < Vector[der]) der--. Vector[PosMenor] = Vector[i]. GraficarValores(Vector. i+1. GraficarValores(Vector. if(izq <= der) { aux = Vector[izq]. } /****************************************************************************/ void Burbuja (int *Vector. j<N. if(Izq < der) QuickSort(Vector. SorteoPorSeleccionRecursiva(Vector. i++) for(j=0. j<N-i. } } /* **************************************************************************/ /* Función : CentrarXCad */ /* Objetivo : Esta función se encarga de Escribir una cadena */ 130 . if(izq < Der) QuickSort(Vector. } } /****************************************************************************/ void QuickSort (int *Vector. der). int pivote.if(i<N-1){ PosMenor = i. N. j. pivote = Vector[(Izq+Der)/2]. der--. int Aux. N). izq. izq++. izq. j++) if(Vector[j] < Vector[PosMenor]) PosMenor = j. Izq. Vector[i] = Aux. int Der) { int izq=Izq. int N){ int i.

} delay(Retardo). for( i=1. (int)rayita). setfillstyle(SOLID_FILL. Arriba. Arriba=5. i++){ Fraccion = (float) Datos[i] / MayorValor. Delta. i++) if(Datos[i]>MayorValor) MayorValor = Datos[i]. if( N ){ MayorValor=Datos[0]. //Eje y for(float rayita=Abajo. int Color){ int largo. Izquierda.Cad). } Izquierda += (Ancho * 2). line(Eje/2. float Fraccion. outtextxy((getmaxx()-largo)/2. ArribaBar). setcolor(RED). Ancho = (int)( (getmaxx()-Eje) / ((N * 2 ) + 1) ). ArribaBar. setcolor(RED). MAGENTA).Fraccion * (Abajo-Arriba) ). Abajo. Delta= (float)(Abajo-Arriba+1)/MayorValor. i<N. MAGENTA). MayorValor=0. Abajo). ArribaBar. Arriba./* centrada en la pantalla en modo gr fico */ /****************************************************************************/ void CentrarXCad(int Fila.Fila. Ancho. 7. i<N. Abajo). setfillstyle(SOLID_FILL. (Izquierda + Ancho). Izquierda += (Ancho * 2). i<N. int PosB. ArribaBar = (int)(Abajo . char *Cad. (Izquierda + Ancho).Fraccion * (AbajoArriba) ). setfillstyle(SOLID_FILL. for( i=0. BLUE). } } else for( i=0. int N. i++){ if(PosA==i || PosB==i){ Fraccion = (float) Datos[i] / MayorValor. ArribaBar = (int)(Abajo . rayita>=Arriba-Delta. bar(Izquierda. (Izquierda + Ancho). (int)rayita. setcolor(Color). } else{ 131 . Abajo). Izquierda = Ancho+Eje. Eje=10. bar(Izquierda. rayita-=Delta) line(3. Eje/2. largo = textwidth(Cad). bar(Izquierda. ArribaBar. } /****************************************************************************/ void GraficarValores(int *Datos. int PosA.40. int Retardo) { int i. Abajo = getmaxy() . if(PosA==-1 || PosB==-1){ setcolor(WHITE).

x. de un color dado y un patrón. } } /****************************************************************************/ /* INICIO FUNCIONES PARA EL MANEJO DEL MOUSE CON INTERRUPCION 33 DEL DOS */ /****************************************************************************/ int IniciarMouse(int &BotonMouse){ union REGS entra. &entra. } /****************************************************************************/ void EsconderCursorMouse(void){ union REGS entra. 8).x.x.settextstyle(TRIPLEX_FONT.int y1.ax = 0x0004. RED). &sale). CentrarXCad(140. int86( 0x33. } /****************************************************************************/ int ClickMouseEnXY( int &x.sale. sale.cx = x. entra. int86 ( 0x33.x.x.x.x. setcolor(ColorAnterior).ax ).x. &sale). &entra. &sale ). HORIZ_DIR. } //************************************************************************** void CursorMouseAXY( int x. sale. */ /****************************************************************************/ void BarraDeColor(int x1. &entra. int &y){ union REGS entra.int x2.x.dx.x.y1. entra.ax = 0x0000. entra. BotonMouse = sale. &sale). } 132 . setfillstyle(Patron. int86( 0x33. y = sale. x = sale. return(sale. entra.ax = 0x0001. entra.ax = 0x0002. } /****************************************************************************/ void MostrarCursorMouse(void){ union REGS entra.x. entra. return ( sale.ax = 0x0003. bar(x1. int y ){ union REGS entra. &sale ).x2.Color). } /****************************************************************************/ /* FIN FUNCIONES PARA EL MANEJO DEL MOUSE CON INTERRUPCION 33 DEL DOS */ /****************************************************************************/ /****************************************************************************/ /* Función : BarColor */ /* Objetivo : Esta funcion se encarga de hacer una barra */ /* en la pantalla.bx). EsconderCursorMouse().bx. int86( 0x33.x.dx = y. int86( 0x33.sale.y2). entra.cx. MostrarCursorMouse().int Patron.int y2. sale. "NO HAY DATOS". int Color){ int ColorAnterior = getcolor(). &entra. &entra.

line(x1. Y2.line(x2-1.y2). X2. else setcolor(WHITE).y1. AltoCuadro=textheight(Cad) + 10. setcolor(Color1).int Color3) { EsconderCursorMouse(). } /****************************************************************************/ /* FUNCION : RealzarCursor */ /* OBJETIVO : Muestra un rectangulo en pantalla. line(x1.y2. MostrarCursorMouse().int Col2. } 133 .y1.line(x1+1.int X2. Y1).Y.int Y2. RecuadroVentana(X. EsconderCursorMouse().1).int Y1.y2-1). char *Cad. floodfill(x1+5. line(x1+1.int y1. line(x1+1.x2-1.line(x1.x2. else setcolor(DARKGRAY).y2).y2-1.int Color2.0. setlinestyle(SOLID_LINE. settextstyle(DEFAULT_FONT.x2. Y2).int x2.y1+1.Col1). if(LargoCuadro==0) LargoCuadro = X + textwidth(Cad) + 10. setcolor(Color2).int Col3.y2.y2-1).y1+1). } /****************************************************************************/ /* Función : Cursor */ /* Objetivo : Realiza recuadro.int ArbAbj){ EsconderCursorMouse(). Y1.int Oprimido){ int AltoCuadro. X2.y1).NORM_WIDTH). con una cadena centrada en su interior.x2-1. Y1. else LargoCuadro = X + LargoCuadro + 10. */ /****************************************************************************/ void RecuadroVentana(int X1. el cual significa */ /* una de las opciones de un men£.HORIZ_DIR. char c[3].y1+5. line(x2-1.LargoCuadro.int Color1. setfillstyle(1.x1. setcolor(Col3).y2-1.y1+1).int Col4. int Y. int LargoCuadro. */ /****************************************************************************/ void RealzarCursor(int x1.1).y2-1.x1+1.line(x1+1.Color3).y1+1). Y2). if(!Oprimido){ BarraDeColor(X. MostrarCursorMouse(). Y1. line(X1. int Col1.x2-1. */ /****************************************************************************/ void Cursor(int X. line(X1.y1).int y2.y1+1.LargoCuadro. if(ArbAbj == 1) setcolor(DARKGRAY).Color3).x2-1.SOLID_FILL.Y+AltoCuadro.int Col5.Y+AltoCuadro. setcolor(Color3). X1. line(X2.Y.y2-1. line(X1. setcolor(Color2). Y2). if(ArbAbj == 1) setcolor(WHITE).y2-1). line(x2./****************************************************************************/ /* Función : MarcoVentana */ /* Objetivo : Dibujar un ReCuadro resaltado o undido.x2. X2.x2-1.

c[1] ='\0'. Col1. Col4. int Yf=480) { // EsconderCursorMouse(). int Xf=638.Cad.Y+5.Y+AltoCuadro. */ */ */ */ int Xo=1. outtextxy(X+5.Col2). Col2. Col5. } /****************************************************************************/ 134 . setfillstyle(SOLID_FILL. Yo. Yo+4. RealzarCursor(Xo. settextstyle(DEFAULT_FONT. MostrarCursorMouse(). Col3.SOLID_FILL.c). DARKGRAY. Actual=1. Col1. Actual ). NoActual). Yf.int Y. return c. } /* *********************************************************************** */ /* Función : AMAYUSCULA */ /* Objetivo : Convierte un caracter en min£scula a may£scula. delay(100). Col5.Cad). Col5. int Col2. delay(100). int Col1. setcolor(Col4). MostrarCursorMouse(). int Yo=460.else{ BarraDeColor(X. CentrarXCad(Yo+5. WHITE). int Col4. MostrarCursorMouse(). WHITE. EsconderCursorMouse(). LargoCadenaMayor. } outtextxy(X+5. Yf-2). char *Cad. */ /**************************************************************************/ void UndidoCursor(int X.int LargoCadenaMayor. Col3. Comentario.Cad. RecuadroVentana(X. Col1. BLUE). int Col5){ const NoActual=0. Xf. LargoCadenaMayor.Y+5. Cursor(X. setcolor(Col5). 1). } /* ************************************************************************ /* Función : EscribirComentarioOpcionMenu /* Objetivo : Muestra avisos correspondientes a opciones del men£ /* ************************************************************************ void EscribirComentarioOpcionMenu(char *Comentario. Y.1).Y+AltoCuadro. Col2. int Col3.Cad. Xf-4. } /**************************************************************************/ /* Función : PulsadoCuadro */ /* Objetivo : Realiza Cursor con una cadena centrada en su */ /* interior y da la sensacion de que se oprime.Y.Y. bar(Xo+4. Cursor(X.LargoCuadro. Col4. Y.LargoCuadro. LargoCadenaMayor. 0. Col2. Col4. BLUE). Y. NoActual ). Col3. c[0] = Cad[0]. Cursor(X. */ /* *********************************************************************** */ char AMayuscula(char c){ if(c>=97 && c<=122) c -= (97-65).

135 ."ANALISIS DE ALGORITMOS". char Tecla. for(i=0. Xm=320. Ym)."Noviembre-2000".0. CentrarXCad(270. int Vector[Max]. BLACK).DARKGRAY.TOP_TEXT). setbkcolor(BLUE). clock_t TiempoInicial. Cad[80]. } CursorMouseAXY(Xm. "\\tc\\bgi"). "Algoritmo de Ordenamiento de Burbuja" }. RealzarCursor(55.getmaxx(). "Algoritmo de Sorteo por fusión de sublistas".HORIZ_DIR.Op[Pos]. setcolor(15).0. NoActual). Fila=442."CIENCIAS DE LA COMPUTACION".0).h int Manejador = DETECT.WHITE. EscribirComentarioOpcionMenu(Comentario[Pos]).CYAN.WHITE. Modo. "Selección".478. for(int j=110.LIGHTGRAY).//ver Time.582. MostrarCursorMouse(). Izq=75.i++) AnchoCursor += textwidth(Op[i])+DeMas.110).i."MergeSort". Ym=Fila-20. } /* *********************************************************************** */ /* FUNCION PRINCIPAL */ /* *********************************************************************** */ void main(){ const Der=77. i<MaxOp.Op[i]. for(i=1. RED)."El ratón NO est delay(2000). CentrarXCad(310. CentrarXCad(190.LIGHTGRAY). Click. setcolor(14). CentrarXCad(150.368).110. for(i=170.i++) PosX[i] = PosX[i-1]+textwidth(Op[i-1])+DeMas. TiempoFinal.DARKGRAY. MaxOp=5. PosX[MaxOp]. i++) Cursor(PosX[i].480. Cursor(PosX[Pos]. Actual=1. NoActual=0. i.j<379.624. initgraph (&Manejador.WHITE.240. AnchoCursor=0. PresentacionInicial(). RealzarCursor(170.CYAN.i.WHITE.110.Actual). Comentario[MaxOp][80]={ "Generar al azar valores para vector".LIGHTGRAY). "Algoritmo de Sorteo por Selección con Recursión".getmaxy()). BLACK).10. Op[MaxOp][20]={"Random". setcolor(WHITE). for(i=0.DARKGRAY.LIGHTGRAY).0.i<MaxOp. "Algoritmo de Sorteo del QuickSort Recursivo". PosX[0] = (getmaxx()-AnchoCursor)/2.370. CentrarXCad(230. Invocar=1. settextstyle(DEFAULT_FONT.240."Burbuja"}.WHITE.WHITE.i+=5) line(325.435. int Pos=0. rectangle(0. settextjustify(LEFT_TEXT. instalado"). &Modo. Invocar = 0. Esc=27.j).Fila.j+=20) line(325.20.LIGHTGRAY.i<480."QuickSort".DARKGRAY.400. MAGENTA).RED.RED.Fila. for(int i=170.LIGHTGRAY. BLACK).63.60. RealzarCursor(16.i<479. DeMas=12. Entrar=13. Aux[Max]. setcolor(11). return."ITESM".397. RealzarCursor(58.void PresentacionInicial(){ EsconderCursorMouse().WHITE.i+=3) line(170.585. if(!IniciarMouse(Click)){ outtextxy(10.i<MaxOp.WHITE."GRUPO 21".

if(i!=Pos){ Cursor(PosX[Pos]. LIGHTGRAY.Op[Pos]. for(. LIGHTGRAY. WHITE.0. CYAN. Invocar = 0. RED.NoActual). Pos++. Cursor(PosX[Pos]. do{ Click = ClickMouseEnXY(Xm. RED. } } } } while (!kbhit() && !Click). i<MaxOp.Fila.0. 136 . WHITE. CYAN. for(i=0.Fila. } MostrarCursorMouse(). while(i<MaxOp && !(Xm>PosX[i] && Xm<PosX[i]+textwidth(Op[i])+DeMas)) i++.0. WHITE. RED. Op[i].Op[Pos]. WHITE. WHITE. break. CYAN. Cursor(PosX[Pos].Fila. Xm=PosX[Pos]+1. if(Pos == MaxOp) Pos=0.. if(Tecla == 0 ){ Tecla = getch(). EscribirComentarioOpcionMenu(Comentario[Pos]). RED. LIGHTGRAY. if(Ym>=Fila && Ym<=Fila+textheight("H")+10){ i=0.Fila.NoActual). WHITE. i++) Cursor(PosX[i]. Pos=i. if(i<MaxOp){ if(Click)// Se hizo "click" en recuadro del men£ Invocar = 1. case Izq: Cursor(PosX[Pos]. CYAN.Xm=PosX[Pos]+1. Actual). CYAN. RED. WHITE. WHITE. RED. LIGHTGRAY. EscribirComentarioOpcionMenu(Comentario[Pos]).Actual). if(!Click){ //Se digitó del teclado Tecla = getch().Op[Pos]. NoActual).Ym). WHITE.0.0. LIGHTGRAY.Fila. WHITE.0. switch(Tecla){ case Der: Cursor(PosX[Pos]. EscribirComentarioOpcionMenu(Comentario[Pos]). RED.Op[Pos].NoActual).Actual). WHITE. Ym=Fila+DeMas.Op[Pos]. LIGHTGRAY. WHITE.Op[Pos].){ if(Invocar){ EscribirComentarioOpcionMenu(Comentario[Pos]). LIGHTGRAY.0. Ym=Fila+DeMas.Fila. CYAN. WHITE. CYAN. WHITE. Cursor(PosX[Pos].Fila.

Op[Pos]. setfillstyle(SOLID_FILL. CYAN. LIGHTGRAY.1. setcolor(WHITE). } Invocar=1. -1.EscribirComentarioOpcionMenu(Comentario[Pos]).1. LIGHTGRAY. // Alt-X case 59: //F1 break. while(Tecla!=Op[i][0] && i<MaxOp) i++.Fila. WHITE. CYAN.Op[Pos]. if(i<MaxOp){ // digitó letra inicial de opción if(i!=Pos){ EscribirComentarioOpcionMenu(Comentario[Pos]).Fila. switch(Pos){ case 0:randomize(). i=0.Fila. EsconderCursorMouse(). Cursor(PosX[Pos]. 638. break. Fila-2). Pos=i. Aux[j] = Vector[j]. WHITE. j<Max. RED. } } } } if(Invocar){ UndidoCursor(PosX[Pos]. RED). getmaxy()-1). getmaxx()-1. setcolor(YELLOW). 137 . j++){ Vector[j] = random(100)+1. BLUE). bar(getmaxx()-111.NoActual). Fila-2).Op[Pos]. EscribirComentarioOpcionMenu(Comentario[Pos]). else{ Tecla=AMayuscula(Tecla). Cursor(PosX[Pos]. WHITE. CYAN.0. 15. } } else{ //Se digitó una tecla del teclado con código ASCII if(Tecla==Esc) return. WHITE. rectangle(1. -1). Pos--. for(int j=0. bar(1. GraficarValores(Vector. WHITE. setfillstyle(SOLID_FILL.Op[Pos]. WHITE. case 45: return. N. LIGHTGRAY.0. if(Tecla==Entrar) Invocar = 1. getmaxy()-31.Actual). RED. 638. WHITE.Actual). LIGHTGRAY. } N=Max. BLUE).0.0.Fila. CYAN. Cursor(PosX[Pos]. RED. if(Pos == -1) Pos = MaxOp-1.

getmaxy()-31. 4: for(j=0." << ends. TiempoInicial = clock(). Cad). getmaxy()-31. TiempoFinal = clock()." << ends. j<N. TiempoInicial = clock(). GraficarValores(Vector. break. TiempoInicial = clock(). -1). -1. getmaxy()-30. TiempoFinal = clock(). getmaxy()-30. j++) Vector[j] = Aux[j]. ostrstream(Cad. setfillstyle(SOLID_FILL. setfillstyle(SOLID_FILL. BLUE). -1). setfillstyle(SOLID_FILL. HORIZ_DIR. getmaxx()-1. getmaxy()-31. bar(getmaxx()-111.case case case case settextstyle(DEFAULT_FONT. GraficarValores(Vector. 80) <<(TiempoFinal-TiempoInicial)/CLK_TCK << " seg. settextstyle(DEFAULT_FONT. setcolor(YELLOW)." << ends. 1: for(j=0. 0. MergeSort(Vector. 1). 0. Cad). j<N. N. N. ostrstream(Cad. N-1). 80) <<(TiempoFinal – TiempoInicial)/CLK_TCK << " seg. getmaxx()-1. j++) Vector[j] = Aux[j]. N. getmaxy()-30. "Tiempo"). HORIZ_DIR. N). GraficarValores(Vector. 1). Cad). ostrstream(Cad. 80) << (TiempoFinal – TiempoInicial)/CLK_TCK << " seg. settextstyle(DEFAULT_FONT. -1). break. bar(getmaxx()-111. j++) Vector[j] = Aux[j]. QuickSort(Vector. outtextxy(getmaxx()-110. getmaxy()-1). TiempoInicial = clock(). getmaxy()-1). N). 3: for(j=0. 0. TiempoFinal = clock(). 2: for(j=0. bar(getmaxx()-111. Burbuja(Vector. GraficarValores(Vector. getmaxx()-1. N-1). BLUE). settextstyle(DEFAULT_FONT. N. getmaxy()-1). -1. getmaxy()-30. 80) <<(TiempoFinal – TiempoInicial)/CLK_TCK 138 . SorteoPorSeleccionRecursiva(Vector. j<N. break. -1). outtextxy(getmaxx()-110. TiempoFinal = clock(). outtextxy(getmaxx()-110. HORIZ_DIR. ostrstream(Cad. 1). -1. 1). setcolor(YELLOW). HORIZ_DIR. j<N. outtextxy(getmaxx()-110. -1. BLUE). break. j++) Vector[j] = Aux[j]. setcolor(YELLOW).

getmaxy()-1). HORIZ_DIR.)." << ends. 1). Tecla=0. // for(. setcolor(YELLOW). BLUE). getmaxy()-30. } MostrarCursorMouse(). bar(getmaxx()-111.. setfillstyle(SOLID_FILL. outtextxy(getmaxx()-110.<< " seg. break. getmaxy()-31. Cad). } Click=0. settextstyle(DEFAULT_FONT. getmaxx()-1. } } /****************************************************************************/ 139 .

En la educación hay que poner el acento en la autonomía. Implica saber correr riesgos y no tener a los seres como posesión. Quien educa con el amor sabe corregir e imponer sanciones sin injusticias. (San Juan Bosco. el temor incita a mentir y acaba con la confianza. LISTAS ENLAZADAS. EDUCACION LIBERADORA En la educación hay que poner el acento en el amor. Se educa para liberar no para esclavizar. amenazas. GONZALO GALLO GONZALEZ "CUATRO AMORES" 140 . Una educación liberadora forma al individuo desde niño para que tome decisiones y sea artífice de su vida. pero no aquellos que brotan de la sobreprotección. el egoísmo o los celos. Supone trazar límites. no en el temor: "Procura más bien hacerte amar. y positivos. no en la dependencia. ni malos tratos. el temor engendra seres acomplejados y pesimistas.SEGUNDA PARTE ESTRUCTURAS AUTOREFERENCIADAS.) El amor nos da personas sinceras. El amor inpulsa a niños y jovenes a ser decididos. que hacerte temer". VARIABLES EN MEMORIA DINAMICA. Eduquemos para una libertad responsable.

Primera Parte Segunda Parte Tercera Parte 141 .

Con la instrucción. De esta forma Cima apunta a la dirección de memoria. que estamos diseñndo. 2. float Altura. } struct PILA{ INFO Info. en esta dirección y con un desplazamiento (offset) en bytes dado por el tamaño de struct PILA. esto es solo una suposición para explicar lo ocurrido. Implementaremos una pila como una lista simplemente enlazada y en memoria dinámica y en la cual cumpliremos la condición de toda pila: "El último elemento que entra es el primero que sale". al puntero Cima. FUNCION INSERTAR EN PILA: METER En la primera invocación a la función meter. Cima ┌─────────┐ │ 0x1000 │ └─────────┘ 0x1000 ╔════════════════╗ ╟────────────────╢ ╟────────────────╢ ╠════════════════╣ ╚════════════════╝ Datos en pila Info puntero Ant la anterior es la correspondiente abstracción en RAM. //Cada nodo de la pila struct INFO{ char Nombre[20]. de 0x1000. y suponiendo dirección en memoria RAM de 0x1000 asignada a Cima y disponible de utilizar. por medio de alguna operación adecuada. la new a asignado el valor entero de 0x1000. // información en la pila PILA *Ant. 142 . En este momento las posiciones de memoria que inician en 0x1000 tendrán "basura". Diremos que Cima vale 0x1000. el puntero a la pila Cima está en NULL. int Edad. en RAM. de la siguiente forma: Cima = new (Pila). Se deberá proceder a asignar información al campo de Info y al puntero ant.PILA COMO LISTA ENLAZADA 1. La implementación de los algoritmos básicos de insertar y eliminar las llamaremos Meter() y Sacar() respectivamente. Se empleará en el diseño de los algoritmos correspondientes que manejarán la pila las siguientes definiciones: typedef struct INFO INFO. INTRODUCCIÓN Como ya habíamos visto. // información que se colocará en pila typedef struct PILA PILA. La única variable que se mantendrá en forma global será el puntero (A pila) Cima. en la cual sus elementos solo pueden ser insertados y eliminados por la cima. es decir está vacía. //anterior nodo de la pila } *Cima = NULL. new del C++ se asignará espacio en la parte de la memoria dinámica. operador. una pila es una estructura de datos lineal.

el cual apunta al primer nodo. En esta y en posteriores invocaciones es necesario utilizar una variable auxiliar de tipo puntero a PILA para cada uno de los nuevos nodos. Supongamos una nueva invocación de la función meter. asignándoselo a Nuevo: Nuevo = new PILA. procedemos por medio de la siguiente instrucción: Nuevo->Ant = Cima. Cima 0x1000 ╔════════════════╗ ║ Carolina ║ 0x1050 ╔════════════════╗ ║ Tania ║ Nuevo 143 . indicando que la lista termina allí. quedando en RAM.56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Datos en pila Info puntero Ant En esta primera invocación de la función meter es todo lo que debe hacer.Supongamos el siguiente código para la asignación a la posición acabada de generar dinámicamente. en este nodo el puntero Ant está en NULL. observe que la lista enlazada que representará la pila inicia en Cima. en el que esta Carolina. Cima->Ant = NULL. A continuación se deberá asignar información al campo de Info. por medio de la función de lectura: LeerRegistro(&Nuevo->Info) correspondiente. A continuación tomamos memoria dinámica con el operador new. Cima ┌─────────┐ │ 0x1000 │ └─────────┘ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1.56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ 0x1050 ╔════════════════╗ ║ Tania ║ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1. así: Cima ┌─────────┐ │ 0x1000 │ └─────────┘ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1.55 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Nuevo ┌─────────┐ │ 0x1050 │ └─────────┘ Para efectuar el enlace de este nuevo nodo y que quede la lista enlazada representando una pila. la llamaremos Nuevo como veremos a continuación: PILA *Nuevo. y la correspondiente abstracción en forma de recuadros en RAM: LeerRegistro(&Cima->Info).

} else 144 . como a continuación se presenta.55 ║ ╠════════════════╣ ║ 0x1000 ║ ╚════════════════╝ ┌─────────┐ │ 0x1050 │ └─────────┘ a continuación actualizamos el valor de Cima. Nuevo->Ant = Cima. Cima ┌─────────┐ │ 0x1050 │ └─────────┘ 0x1050 ╔════════════════╗ ║ Tania ║ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1. se ve que se puede resumir al caso general. if(Nuevo){ // Hay espacio en RAM para el nuevo nodo de Pila LeerRegistro(&Nuevo->Info).56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Nuevo ┌─────────┐ │ 0x1050 │ └─────────┘ Resumiendo el código de la función meter. } else{ // caso general Nuevo = new PILA. } } Observando el anterior código.55 ║ ╠════════════════╣ ║ 0x1000 ║ ╚════════════════╝ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1. en una primera versión. agregando la validación del caso de memoria llena: Meter(){ PILA *Nuevo. Cima->Ant = NULL. Nuevo = new PILA. Nuevo->Ant = Cima. LeerRegistro(&Cima->Info).┌─────────┐ │ 0x1000 │ └─────────┘ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1. y rearreglando la figura de la abstrcción: Cima = Nuevo. es el siguiente: Meter(){ PILA *Nuevo.56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1. LeerRegistro(&Nuevo->Info). para cuando la pila está vacía y el caso general. if(!Cima){ // Pila está vacía Cima = new Pila.

Cima = Cima->Ant.55 ║ ╠════════════════╣ ║ 0x1000 ║ ╚════════════════╝ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1.55 ║ ╠════════════════╣ ║ 0x1000 ║ ╚════════════════╝ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1. } Como ejemplo verifique la inserción de otro nodo.75 ║ ╠════════════════╣ ║ 0x1050 ║ ╚════════════════╝ 0x1050 ╔════════════════╗ ║ Tania ║ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1. más no fisicamente. y que queda en memoria RAM de la siguiente forma: Cima ┌─────────┐ │ 0x1100 │ └─────────┘ 0x1100 ╔════════════════╗ ║ Valentina ║ ╟────────────────╢ ║ 1 ║ ╟────────────────╢ ║ 0. Se procede a liberar la memoria dinámica apuntada por Aux con la instruccion delete. vale 0x1050 //Cima vale 0x1100 //Cima->Ant vale 0x1050. usted mismo.55 ║ ╠════════════════╣ ║ 0x1000 ║ ╚════════════════╝ 0x1000 ╔════════════════╗ ║ Carolina ║ ╟────────────────╢ ║ 16 ║ ╟────────────────╢ ║ 1. y de esta forma eliminando el que estaba inicialmente en la Cima. FUNCION ELIMINAR DE PILA: SACAR De una pila siempre se deben eliminar el elemento que está en Cima. a partir de ahora Cima Observe que a partir de ahora Cima toma el valor de 0x1050.cout << "MEMORIA LLENA".56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ 145 . apuntado al siguiente nodo de la pila.56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Ya habrá caido en cuenta el por qué de la utilización de la variable Aux. Aux = Cima. así de la figura anterior seguiremos los siguientes pasos: PILA *Aux. solo lógicamente. así: delete(Aux).56 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Nuevo ┌─────────┐ │ 0x1100 │ └─────────┘ 3. así: Cima ┌─────────┐ │ 0x1050 │ └─────────┘ Aux ┌─────────┐ │ 0x1100 │ └─────────┘ 0x1100 ╔════════════════╗ ║ Valentina ║ ╟────────────────╢ ║ 1 ║ ╟────────────────╢ ║ 0.75 ║ ╠════════════════╣ ║ 0x1050 ║ ╚════════════════╝ 0x1050 ╔════════════════╗ ║ Tania ║ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1. Cima ┌─────────┐ │ 0x1050 │ └─────────┘ 0x1050 ╔════════════════╗ ║ Tania ║ ╟────────────────╢ ║ 23 ║ ╟────────────────╢ ║ 1.

} cout << "En pila existen " << N << " elementos en espera\n".Resumiendo. } else cout << "Pila está vacía".h> const char NombreArchivo[15]="PILA. int N=0. } 4. solo se debe tener acceso al elemento en la cima de la pila. } 5.h> <fstream.h> <stdio. while (p){ N++. PROGRAMA DE EJEMPLO DE ESTRUCTURA DE DATOS PILA El siguiente programa.h> <cadenas. es el siguiente: un nodo de la pila Sacar(){ PILA *Aux.h> <iomanip. siendo dogmáticos. delete(Aux). cout << "Eliminado el nodo de la persona: " << Cima->Info. el correspondiente código para eliminar inplementada en una lista enlazada.Edad <<" años" << endl. struct Datos { 146 .CPP. a continuación mostramos código para recorrer la lista enlazada en la que está la pila: ListarPila(){ Pila *p.h> <graphics. } else cout << "Pila está vacía". FUNCION LISTAR ELEMENTOS EN PILA Aunque estrictamente.Nombre <<" tiene " <<p->Info. implementa la estructura de datos pila como una lista simplemente enlazada en memoria dinámica.Nombre << " de la cima de la pila" << endl. if(Cima){ p = Cima. p = p->Ant.LST". if(Cima){ Aux = Cima. PILALIST. Observe los cambios efectuados en las funciones básicas. buscando una mayor generalidad del código y evitar repeticiones en el mismo.h> <conio. cout <<p->Info. #include #include #include #include #include #include #include <iostream.

} } //--------------------------------------------------------------------------// void CapturarDatos() { Datos Item. Nuevo->sig = NULL. struct PILA *sig. return(0). cout << "El nombre del autor:". }. } else { Nuevo->Datos = Item. Nuevo = new(PILA).NumeroEjemplares.char Titulo[20]. clrscr(). char Autor[15]. cout << "\nColocar un libro en pila"<< endl. struct PILA { struct Datos Datos. } else 147 . gets(Item. int NumeroEjemplares. MeterEnPila(Item). cout << "El nombre del libro :". char Cota[10]. } //--------------------------------------------------------------------------// void SacarLibroDePila() { struct PILA *p.Autor). if(Cima) Nuevo->sig = Cima. cin >> Item. cout<<"Número de ejemplares: ". if(Nuevo==NULL) { cout << "\nMemoria llena" << endl. cout<<"El valor del libro: ". } *Cima = NULL. clrscr().Titulo). cin >> Item. clrscr().Cota). Cima = Nuevo. cout << "============================"<< endl.CostoLibro. gets(Item. //--------------------------------------------------------------------------// int MeterEnPila(Datos Item) { struct PILA *Nuevo. float CostoLibro. if(Cima==NULL) { cout<<"\nNo hay registros en memoria"<<endl. cout<<"El código Dewey del libro: ". gets(Item. return(1).

} getch().Titulo << setw(15) << p->Datos. NumLibros=0. if(Cima==NULL){ cout<<"No hay ningún libra en la pila". } //--------------------------------------------------------------------------// void ListarLibrosEnPila() { clrscr(). 148 . else { cout<< "Digite el nombre del libro que desea buscar: ". cout << setiosflags(ios::right) << setw(2) << NumTitulos << " " << setiosflags(ios::left) << setw(20) << p->Datos. } cout << "\nTotal de títulos: " << NumTitulos << "\nTotal de libros en existencia: " << NumLibros.{ cout << "\nLibro en la cima de la pila:" << endl << "=================================" << endl << "Nombre del libro: " << Cima->Datos. NumLibros += p->Datos.Cota << setiosflags(ios::right | ios::showpoint | ios::fixed) << setprecision(2) << setw(15) << p->Datos.NumeroEjemplares << endl.CostoLibro << setiosflags(ios::right) << setw(8) << p->Datos. Cima = Cima->sig.NumeroEjemplares. gets(item).Cota << endl << "Valor de cada ejemplar: "<< Cima->Datos.Autor << setw(10) << p->Datos. while(p) { NumTitulos++. Título Autor Cota" << " Valor Ejemplares\n\n". } else { int NumTitulos=0. } } //--------------------------------------------------------------------------// void ConsultarDatoEnPila() { char item[20].Titulo << endl << "Codigo del libro: "<< Cima->Datos. if(Cima==NULL) cout<<"No hay libros en la Pila". clrscr(). p = p->sig.CostoLibro << endl << "Número de ejemplares en existencia: " <<Cima->Datos. p = Cima. delete(p). struct PILA *p=Cima.NumeroEjemplares. cout << "No.

NumeroEjemplares << " ejemplares". } else { cout << "\nTiene el código: " << p->Datos.close().Titulo << setw(15) << p->Datos. ios::out|ios::binary|ios::trunc).Autor << setw(10) << p->Datos.NumeroEjemplares << endl. // invocación recursiva cout << setiosflags(ios::left) << setw(20) << p->Datos.struct PILA *p.open(NombreArchivo.Cota << " un valor de $" << p->Datos. } } getch(). ListaInversaPila(p->sig). } } //--------------------------------------------------------------------------// void GrabarPilaEnDisco(){ fstream Archivo.Titulo)!=0) p=p->sig. sizeof(Registro) ) ) MeterEnPila(Registro).read( (char *)&Registro. if(!p) { cout<<"No encontrado".Cota << setiosflags(ios::right | ios::showpoint | ios::fixed) << setprecision(2) << setw(15) << p->Datos. Archivo. } } //--------------------------------------------------------------------------// void CargarDesdeDiscoPila(){ fstream Archivo. while(Archivo. Archivo.ios::in|ios::binary).p->Datos.open(NombreArchivo. Datos Registro. Archivo. else{ 149 . if (!Archivo) cout << "Error en la apertura del archivo \a".CostoLibro << " y hay " << p->Datos. p = Cima.CostoLibro << setiosflags(ios::right) << setw(6) << p->Datos. while(p && CompararCadenas(item. } //--------------------------------------------------------------------------// void ListaInversaPila(PILA *p) // se efectúan invocaciones recursivas { if (p) { clrscr(). if(Archivo){ Cima = NULL.

p = Cima.NumeroEjemplares / SumaNumeroEjemplares. while (p){ SumaNumeroEjemplares += p->Datos.close(). q = p. while(p){ porcentaje =(float) p->Datos.struct PILA *p. settextstyle(SMALL_FONT. profundidad.Titulo). initgraph( &ManejadorGrafico. settextstyle(GOTHIC_FONT. p = p->sig. profundidad. ModoGrafico. while ( p ) { Archivo. getmaxx(). arriba. ancho. setbkcolor(BLUE).0.30.0. setfillstyle(SOLID_FILL.( (int)(porcentaje * (abajo-arriba) ) ). int izquierda. getmaxy()/2 . float porcentaje.8). } ancho = (int)( (getmaxx()) / ((NumeroTitulos * 2 ) + 1) ). settextstyle(1. *q. } Archivo. setcolor(WHITE). } } else{ setcolor(RED). PILA *p. arriba. "TITULOS"). direccion.10). arriba. p = Cima. "NO HAY DATOS"). arriba = 30. rectangle(0. izquierda = ancho. "c:\\tc\\bgi" ). tamaño ) outtextxy(izquierda+ancho/2. SumaNumeroEjemplares=0. 1).write((char *)&p->Datos. abajo. getmaxy()-10 . p = p->sig. setcolor(RED). (izquierda + ancho). setcolor(CYAN). } } //--------------------------------------------------------------------------// void GraficarInfoPila(){ int ManejadorGrafico = DETECT. delete(q). setcolor(YELLOW). cleardevice(). p->Datos. outtextxy(10. bar3d(izquierda. p = p->sig. 0. &ModoGrafico. if (Cima){ p = Cima. outtextxy(getmaxx()/8.// (tipo letra. abajo = getmaxy() .NumeroEjemplares. sizeof(p->Datos)). getmaxy()). NumeroTitulos++. abajo. } 150 . izquierda += (ancho * 2). int NumeroTitulos=0.1. profundidad = (int) (ancho / 8).MAGENTA). arriba = (abajo) .0).

break. generada al azar. 151 . break. case 'C' : ConsultarDatoEnPila().){ ListarLibrosEnPila(). break. for(. case 'S' : SacarLibroDePila(). Al colocar cada carta. switch (opcion) { case 'M' : CapturarDatos(). break. } //--------------------------------------------------------------------------// void main(){ int opcion. case 'T' : GrabarPilaEnDisco(). } } } PROGRAMA A REALIZAR COMO EJERCICIO Con el programa de CONCENTR. cout << "\n\nMeter Sacar Consultar Recursión Graficar Terminar: ". sobre una mesa. case 'R' : ListaInversaPila(Cima).. para cuando se quiera ser retirada de encima del maso de cartas la última puesta en él. return. case 'G' : GraficarInfoPila(). closegraph().getch(). muestre mazo de cartas arrumado en forma de pila.CPP como modelo y herramienta. break. se debe ir almacenando en una estructura de datos Pila (implementada como una lista enlazada y en memoria dinámica). opcion = AMayuscula( getch() ). getch(). CargarDesdeDiscoPila().

los punteros a COLA: Frente y Final. // información en espera en la cola COLA *Atras. Como queda en cola un solo nodo. 152 . int Edad. //siguiente nodo de cada elemento en cola } *Frente = NULL. *Final=NULL. // información que se colocará en cola typedef struct COLA COLA. FUNCION DE INSERTAR EN COLA Al inicio del programa la cola estará vacía. al puntero Final deberemos asignarle el mismo valor de Frente. INTRODUCCIÓN Como ya hemos visto una cola es una estructura de datos en la cual sus elementos solo pueden ser insertados por un extremo y eliminados por el otro. La definición de la estructura de datos estará dada por: typedef struct INFO INFO. En toda cola el primero que llega será atendido primero. en este capítulo. float Altura. La instrucción new efecturá lo siguiente en RAM: Cima ┌─────────┐ │ 0x2000 │ └─────────┘ 0x2000 ╔════════════════╗ ╟────────────────╢ ╟────────────────╢ ╠════════════════╣ ╚════════════════╝ Datos en cola Info puntero Atras A continuación se debe asignar la información del nodo y al campo de puntero Atras asignarle NULL. veamos el código y el correspondiente dibujo: if(Frente == NULL){ Frente = new COLA.COLA COMO UNA LISTA ENLAZADA 1. Para la implementación de la cola. 2. utilizaremos la estructura de datos lista enlazada en memoria dinámica. LeerRegistro(&Frente->Info. Para la inserción se presenta el caso especial siguiente: if (Frente == NULL){ Frente = new COLA. Se mantendrán en memoria RAM dos variables globales. //Cada nodo de la cola struct INFO{ char Nombre[20]. así mismo cuando posteriormente durante la ejecución del programa podría ser que en algún momento quedaré vacía. en estas dos circunstancias Frente estará en NULL. } struct COLA{ INFO Info.Nombre).

y es allí donde le asignaremos valores para cada registro de la lista enlazada que manejará la estructura de datos cola.65 ║ ╠════════════════╣ ║ NULL ║ Puntero Atras ╚════════════════╝ Para que este nuevo nodo llegue al final de la cola. } 0x2000 ╔════════════════╗ ║ Vanessa ║ Final ╟────────────────╢ ┌─────────┐ ║ 10 ║ │ 0x2000 │ ╟────────────────╢ └─────────┘ ║ 1.40 ║ ╠════════════════╣ ║ 0x2000 ║ ╚════════════════╝ 0x2000 ╔════════════════╗ ║ Marcela ║ ╟────────────────╢ ║ 13 ║ ╟────────────────╢ ║ 1.4 ║ ╠════════════════╣ ║ NULL ║ Puntero Atras ╚════════════════╝ Frente ┌─────────┐ │ 0x2000 │ └─────────┘ Recuerde que la instrucción new.Frente->Atras = NULL. Al insertar otro nodo cuando ya existe al menos uno. a partir de esta dirección y con un desplazamiento dado por el tamaño en bytes de la struct COLA. debemos codificar las instrucciones: Final->Atras = Nuevo. Frente ┌─────────┐ │ 0x1500 │ └─────────┘ 0x1500 ╔════════════════╗ ║ Vanessa ║ Final ╟────────────────╢ ┌─────────┐ ║ 10 ║ │ 0x1500 │ ╟────────────────╢ └─────────┘ ║ 1. asigna al puntero Frente.65 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Final ┌─────────┐ │ 0x2000 │ └─────────┘ En resumen el código para inseertar un nodo en una lista enlazada y que represente la abstracción de la estructura de datos cola será: InsertarEnCola(){ COLA *Nuevo. Nuevo = new COLA. es necesario utilizar una vaariable auxiliar que llamaremos *Nuevo: COLA *Nuevo. Final = Nuevo. if(Frente == NULL){ 153 . será reservado. Frente ┌─────────┐ │ 0x1500 │ └─────────┘ 0x1500 ╔════════════════╗ ║ Vanessa ║ ╟────────────────╢ ║ 10 ║ ╟────────────────╢ ║ 1. Final = Frente. una dirección de memoria dinámica en RAM. LeerRegistro(&Nuevo->Info).40 ║ ╠════════════════╣ ║ NULL ║ Puntero Atras ╚════════════════╝ 0x2000 ╔════════════════╗ ║ Marcela ║ Nuevo ╟────────────────╢ ┌─────────┐ ║ 13 ║ │ 0x2000 │ ╟────────────────╢ └─────────┘ ║ 1. Nuevo->Atras = NULL.

reescríbalo usted mismo como ejercicio. LeerRegistro(&Frente->Info. AtenderCola(){ if(Frente){ cout << "Atendido: " << Frente->Info.9 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Final ┌─────────┐ │ 0x2500 │ └─────────┘ 3.4 ║ ╠════════════════╣ ║ 0x2000 ║ ╚════════════════╝ Frente ┌─────────┐ │ 0x2000 │ └─────────┘ 0x2000 ╔════════════════╗ ║ Marcela ║ ╟────────────────╢ ║ 13 ║ ╟────────────────╢ ║ 1. delete (Aux). A continuación el nodo apuntado por quedando en definitiva toda la función así: Aux. Frente->Atras = NULL. } 154 . LeerRegistro(&Nuevo->Info.65 ║ ╠════════════════╣ ║ 0x2500 ║ ╚════════════════╝ 0x2500 ╔════════════════╗ ║ Natalia ║ ╟────────────────╢ ║ 3 ║ ╟────────────────╢ ║ 0. Recuerde que para cumplir el requisito de la cola: "El primero que entra el primero que sale".9 ║ ╠════════════════╣ ║ NULL ║ ╚════════════════╝ Final ┌─────────┐ │ 0x2500 │ └─────────┘ cout << "Atendido: " << Frente->Info. Final = Frente. siempre debemos eliminar el nodo apuntado por la variable Frente. Nuevo->Atras = NULL.Frente = new COLA.Nombre). } else{ Nuevo = new COLA. } Observe que es posible hacerle al algoritmo algunas simplificaciones. con la figura anterior tendremos: 0x1500 ╔════════════════╗ ║ Vanessa ║ ╟────────────────╢ ║ 10 ║ ╟────────────────╢ ║ 1. FUNCION ELIMINAR DE COLA: ATENDER Con la función Atender se eliminará un nodo de la estructura de datos cola. deberá liberarse con delete.Nombre << " del frente de la cola" << endl.Nombre).Nombre << " del frente de la cola" << endl. Aux = Frente. Y verifique insertando otro nuevo nodo de tal suerte que quede la cola como la mostrada a continuación: Frente ┌─────────┐ │ 0x1500 │ └─────────┘ 0x1500 ╔════════════════╗ ║ Vanessa ║ ╟────────────────╢ ║ 10 ║ ╟────────────────╢ ║ 1. Final = Nuevo. Aux = Frente.4 ║ ╠════════════════╣ ║ 0x2000 ║ ╚════════════════╝ 0x2000 ╔════════════════╗ ║ Marcela ║ ╟────────────────╢ ║ 13 ║ ╟────────────────╢ ║ 1. Frente = Frente->Atras. Frente = Frente->Atras.65 ║ ╠════════════════╣ ║ 0x2500 ║ ╚════════════════╝ 0x2500 ╔════════════════╗ ║ Natalia ║ ╟────────────────╢ ║ 3 ║ ╟────────────────╢ ║ 0.

implementada como una lista simplemente enlazada en memoria dinámica.Nombre <<" tiene " <<p->Info. PROGRAMA DE APLICACION DE LA ESTRUCTURA DE DATOS COLA Programa de estructura de datos cola.h> #include <io. } cout << "En cola existen " << N << " elementos en espera\n". cout <<p->Info.h> #include <ctype.h> #include <fcntl. p = p->Atras. esté bien seguro de esto.CPP #include <iostream. if(Frente){ p = Frente. } Si ha entendido hasta aquí. 5. y así mismo el observe el manejo de archivos con el archivo a incluir fcntl. a continuación mostramos código para recorrer la lista enlazada en la que está la cola: ListarCola(){ COLA *p.else cout << "Cola vacía". struct INFO{ 155 .h> // NULL #include <conio.h. typedef struct NODO NODO.h> #include <stdlib. en vez de new. } Como ejercicio elimine uno por uno los dos nodo que quedan en el dibujo anterior. int N=0. } else cout << "Cola está vacía". FUNCION LISTAR ELEMENTOS EN COLA Aunque estrictamente.h> #define ARCHIVO "AGENDA. 4.CLT" typedef struct INFO INFO. //COLALIST.h> #include <dos. observe que el código sigue funcionando cuando la cola esté vacía.h> #include <string. y free(en vez de delete). Sehan utilizado las instrucciones tradicionales del C: malloc. solo se debe tener acceso al elemento del Frente de la cola. notará que los algoritmos con listas enlazadas son mucho más simples que los correspondientes a los efectuados con vectores.Edad <<" años" << endl.h> #include <stdio. siendo dogmáticos. while (p){ N++.

nombre<<" de " <<q->info. Nuevo->sig = NULL. q = p. while ( p ) { _write( NArch. cout <<"\nEliminado: "<<q->info. }. const int BytesNodo=sizeof(NODO). NArch = _open(ARCHIVO. cin >> Nuevo->info. free(q). Final = Nuevo.edad.edad <<" años". O_WRONLY). (char *)&p->info. _close(NArch). 156 .int edad. *Final=NULL. } void GrabarColaLista(){ int NArch. gets(Nuevo->info. } *Frente=NULL. void Insertar (){ NODO *Nuevo. p = Frente. NODO *sig. if (!Frente) cout <<"\nNo hay INFO". sizeof(p->info) ). char nombre[25]. struct NODO{ INFO info. free(q). else{ cout <<"\n\nDigite nombre: ". } getch().nombre). Frente = Frente->sig. *q. else{ q = Frente. if(!Frente) Frente = Nuevo. else Final->sig = Nuevo. 32). } } void Eliminar(){ NODO *q. p = p->sig. NArch = _creat(ARCHIVO. } _close(NArch). cout <<"Digite edad: ". if ( (Nuevo =(NODO *) malloc(BytesNodo) ) == NULL ) cout <<"No hay memoria suficiente". NODO *p.

nombre << " " << p->info. Nuevo = (NODO *) malloc(BytesNodo). if ( (NArch = _open(ARCHIVO.} void CargarColaLista(){ int NArch. } } void ListarCola(){ NODO *p. delay(1000). p = p->sig. NODO *Nuevo. } _close(NArch). O_RDONLY) ) == -1){ cout <<"Archivo no existe \a". sizeof(Nuevo->info) )!=0) { Nuevo->sig = NULL. } else{ Frente = Final = NULL. } } 157 .edad << "\n". while(p){ cout << p->info. Nuevo =(NODO *) malloc(BytesNodo). if (!Frente) Frente = Final = Nuevo. (char *)&Nuevo->info. while ( _read(NArch. else Final = Final->sig = Nuevo. clrscr(). p = Frente.

case 'E':Eliminar(). la cola está vacía.edad │ ├─────────────┤ │ info. do{ ListarCola(). a continuación la instrucción if(!Frente) equivale a if(!NULL) que es verdadero. Nombre TANIA tendremos: 158 .void main(){ char op. Terminar: ". CargarColaLista(). break. nombre y se asigna NULL a nuevo->sig a continuación. si digitamos edad 21. switch (op){ case 'I':Insertar(). } A continuación prueba de anterior progrma COLALIST. por esto sigue en: Frente=Nuevo.nombre │ ├─────────────┤ │ *sig │ └─────────────┘ Se digitan edad. } } while (op != 'T').CPP Frente ┌──────┐ │ Null │ └──────┘ Nuevo ┌──────┐ │ 1000 │ └──────┘ Final ┌──────┐ │ Null │ └──────┘ 1000 ┌──────────┐ │ 13 │ ├──────────┤ │ CAROLINA │ ├──────────┤ │ NULL │ └──────────┘ ejecución manual de la función Insertar() del NODO ┌─────────────┐ │ info. break. quedando en memoria y terminando la función: Frente ┌──────┐ │ 1000 │ └──────┘ Final ┌──────┐ │ 1000 │ └──────┘ Nuevo ┌──────┐ │ 1000 │ └──────┘ 1000 ┌──────────┐ │ 13 │ ├──────────┤ │ CAROLINA │ ├──────────┤ │ NULL │ └──────────┘ En una nueva invocación. cout <<"\nInsertar Eliminar op = toupper(getch()). GrabarColaLista(). y luego Final=Nuevo.

el cual es falso.Frente ┌──────┐ │ 1000 │ └──────┘ Final ┌──────┐ │ 1000 │ └──────┘ Nuevo ┌──────┐ │ 2000 │ └──────┘ La instrucción if(!Frente) se pasa a evaluar la parte quedando en memoria: 1000 2000 ┌──────────┐ ┌──────────┐ │ 13 │ │ 21 │ ├──────────┤ ├──────────┤ │ CAROLINA │ │ TANIA │ ├──────────┤ ├──────────┤ │ NULL │ │ NULL │ └──────────┘ └──────────┘ equivale a if(!1000). y luego Final=Nuevo. 1000 2000 ┌──────────┐ ┌──────────┐ │ 13 │ │ 21 │ ├──────────┤ ├──────────┤ │ CAROLINA │ │ TANIA │ ├──────────┤ ├──────────┤ │ 2000 ├─>┤ NULL │ └──────────┘ └──────────┘ Final->sig Frente ┌──────┐ │ 1000 │ └──────┘ digitamos edad Nuevo ┌──────┐ │ 2000 │ └──────┘ 23 3000 ┌──────────┐ Frente │ 23 │ ┌──────┐ ├──────────┤ │ 1000 │ │ NELCY │ └──────┘ ├──────────┤ │ NULL │ ->Nuevo sig └──────────┘ Final ┌──────┐ │ 2000 │ └──────┘ Nombre NELCY Final ┌──────┐ │ 2000 │ └──────┘ quedando en Nuevo ┌──────┐ │ 3000 │ └──────┘ La instrucción if(!Frente) es falsa. ya hay nodos en la lista. Efectuemos una invocación ahora a la función Eliminar(). por esto en el else a Final->sig=Nuevo y luego a Final=Nuevo de la siguiente forma: Frente ┌──────┐ │ 1000 │ └──────┘ Final ┌──────┐ │ 3000 │ └──────┘ 1000 2000 3000 ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 13 │ │ 21 │ │ 23 │ ├──────────┤ ├──────────┤ ├──────────┤ │ CAROLINA │ │ TANIA │ │ NELCY │ ├──────────┤ ├──────────┤ ├──────────┤ │ 2000 ├─>┤ 3000 ├─>┤ NULL │ └──────────┘ └──────────┘ └──────────┘ Nuevo ┌──────┐ │ 3000 │ └──────┘ Efectúe otras dos inserciones más para estar seguro que entendió. 1000 2000 ┌──────────┐ ┌──────────┐ │ 13 │ │ 21 │ ├──────────┤ ├──────────┤ │ CAROLINA │ │ TANIA │ ├──────────┤ ├──────────┤ │ 2000 ├─>┤ NULL │->Nuevo sig └──────────┘ └──────────┘ En una memoria: tercera invocación. la instrucción if(! Frente) es falsa por esto el algoritmo continuará en else{ q= Frente 159 . por esto de else: final->sig=Nuevo.

CPP el cual muestra baraja francesa arrumada en forma de pila. 160 . Retire una carta cada vez y colóquela sobre "la mesa" una al lado de la otra con la cara hacia arrriba y como si estuvieran en cola.Frente=Frente->sig q Frente Final ┌──────┐ ┌──────┐ ┌──────┐ │ 1000 │ │ 2000 │ │ 3000 │ └──────┘ └──────┘ └──────┘ 1000 2000 3000 ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 13 │ │ 21 │ │ 23 │ ├──────────┤ ├──────────┤ ├──────────┤ │ CAROLINA │ │ TANIA │ │ NELCY │ ├──────────┤ ├──────────┤ ├──────────┤ │ 2000 ├─>┤ 3000 ├─>┤ NULL │ └──────────┘ └──────────┘ └──────────┘ siguiendo en pantalla "Eliminando CAROLINA de 13 años" y la dirección del Nodo a que apunte q quedando: q ┌──────┐ │ 1000 │ └──────┘ Frente ┌──────┐ │ 2000 │ └──────┘ 2000 3000 ┌──────────┐ ┌──────────┐ │ 21 │ │ 23 │ ├──────────┤ ├──────────┤ │ TANIA │ │ NELCY │ ├──────────┤ ├──────────┤ │ 3000 ├─>┤ NULL │ └──────────┘ └──────────┘ Final ┌──────┐ │ 3000 │ └──────┘ Ensaye a eliminar los otros dos nodos. claro que debe haber un máximo de cartas a colocar de esta forma. para luego retirarlas a la manera como se hace en una cola y devolverlas a la pila. efectuado a partir de CONCENTR. mostrando su secuencia. PROGRAMA A REALIZAR COMO EJERCICIO Con el programa del capítulo anterior sobre pilas.

LISTA ENLAZADA ORDENADA Una lista enlazada es un por medio de punteros. dependiendo del sistema de datos a modelar. Cab. variable. Cab. A manera de aproximación veamos una serie de operaciones las cuales podríamos realizar sobre una lista simplememte enlazada y clasificada por la clave info: Después de la inserción de un item D: 2500 Cab ┌─────┐ ┌────┐ │ D │ │2500│-> ├─────┤ una lista con un solo NODO └────┘ │nulo │ └─────┘ Se inserta un item E: Cab ┌────┐ │2500│--> └────┘ 2500 ┌─────┐ │ D │ ├─────┤ │3000 │--> 3000 ┌─────┐ │ E │ ├─────┤ │nulo │ una lista con dos NODOS 161 . Cab ┌────┐ │nulo│ └────┘ la lista está vacía una de las desventajas de las listas simplemente enlazadas está en el hecho de que para accesar cualquier nodo de la lista se debe recorrer siempre empezando por el nodo de cabeza. de esta forma el registro a representar tendrá la siguiente sintaxis: struct NODO{ char info. La abstracción es conjunto de nodos los cuales entán encadenados entre sí Cada nodo de la lista enlazada es un valor de una está compuesta básicamente de dos campos: el campo de nodo y el campo del puntero al siguiente nodo en la la siguiente: ┌─────────┐ │ INFO │ ├─────────┤ │*Puntero │ └─────────┘ El campo de INFO contendrá el número de subcampos que se crea conveniente. esta variable información o datos del lista. } *Cab=NULL. Cab es abreviatura de la palabra cabeza. la cual deberá apuntar a una variable de tipo NODO. NODO *sig. el inicializarla en NULL(nulo) nos da a entender que la lista enlazada está vacía. en las explicaciones siguientes se considera este campo como de un solo subcampo y de tipo caracter. de esta forma se ha definido una variable puntero.

//se crea un Nuevo NODO 162 .└─────┘ └─────┘ Se inserta un item B: 4000 ┌─────┐ │ B │ ├─────┤ │2500 │--> └─────┘ Se inserta un item M: 4000 Cab ┌─────┐ ┌────┐ │ B │ │4000│--> ├─────┤ └────┘ │2500 │--> └─────┘ Cab ┌────┐ │4000│--> └────┘ 2500 ┌─────┐ │ D │ ├─────┤ │3000 │--> └─────┘ 3000 ┌─────┐ │ E │ ├─────┤ │nulo │ └─────┘ 2500 ┌─────┐ │ D │ ├─────┤ │3000 │--> └─────┘ 3000 ┌─────┐ │ E │ ├─────┤ │4500 │--> └─────┘ 4500 ┌─────┐ │ M │ ├─────┤ │nulo │ └─────┘ Se inserta un item H: 4000 Cab ┌─────┐ ┌────┐ │ B │ │4000│-->├─────┤ └────┘ │2500 │-> └─────┘ 2500 ┌─────┐ │ D │ ├─────┤ │3000 │-> └─────┘ 3000 ┌─────┐ │ E │ ├─────┤ │5000 │-> └─────┘ 5000 ┌─────┐ │ H │ ├─────┤ │4500 │-> └─────┘ 4500 ┌─────┐ │ M │ ├─────┤ │nulo │ └─────┘ Eliminación de un nodo con info E: Cab ┌────┐ │4000│--> └────┘ 4000 ┌─────┐ │ B │ ├─────┤ │2500 │--> └─────┘ 2500 ┌─────┐ │ D │ ├─────┤ │5000 │--> └─────┘ 5000 ┌─────┐ │ H │ ├─────┤ │4500 │--> └─────┘ 4500 ┌─────┐ │ M │ ├─────┤ │nulo │ └─────┘ Eliminación de un nodo con info B: Cab ┌────┐ │2500│--> └────┘ 2500 ┌─────┐ │ D │ ├─────┤ │5000 │--> └─────┘ 5000 ┌─────┐ │ H │ ├─────┤ │4500 │--> └─────┘ 4500 ┌─────┐ │ M │ ├─────┤ │nulo │ └─────┘ ALGORITMO DE INSERCION EN LISTA ENLAZADA CLASIFICADA ASCENDENTEMENTE: El algoritmo para la inserción de valores en una lista simplemente enlazada y clasificada en orden ascendente por una clave es el siguiente: p = nulo. //punteros auxiliares para recorrer lista q = Cab. Nuevo = new NODO.

//punteros auxiliares para recorrer lista q = Cab. quedando en memoria RAM según la siguiente abstracción: Cab ┌────┐ │1000│-> └────┘ p ┌────┐ │nulo│ └────┘ 1000 ┌─────┐ │ B │ ├─────┤ │2000 │-> └─────┘ q ┌────┐ │1000│ └────┘ 2000 ┌─────┐ │ E │ ├─────┤ │3000 │-> └─────┘ item ┌────┐ │ I │ └────┘ 3000 ┌─────┐ │ G │ ├─────┤ │1500 │-> └─────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │ └─────┘ 4000 ┌─────┐ │ I │ ├─────┤ │nulo │ └─────┘ Nuevo ┌────┐ │4000│ └────┘ p y q son punteros auxiliares con los cuales recorreremos la lista. Nuevo->info = item.Nuevo->sig = nulo. //se crea un nuevo NODO Nuevo->sig = nulo. se encuentra en memoria la siguiente lista enlazada: Cab ┌────┐ │1000│-> └────┘ 1000 ┌─────┐ │ B │ ├─────┤ │2000 │--> └─────┘ 2000 ┌─────┐ │ E │ ├─────┤ │3000 │--> └─────┘ 3000 ┌─────┐ │ G │ ├─────┤ │1500 │--> └─────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │ └─────┘ 1. q = q->sig. buscando el sitio donde debe quedar el nuevo item. } else { if(!q) // se inserta de último el Nuevo NODO p->sig = Nuevo. Cab = Nuevo. y según el siguiente código: 163 . } } Para la explicación del algoritmo supondremos. Nuevo = new (NODO). Se inserta a continación un item I: p = nulo. //se inserta intermedio en lista Nuevo->sig = q. while(q && item>q->info) { p = q. 'I' a insertar. por conveniencia. Nuevo->info = item. } if(!p) { //se inserta de primero el Nuevo NODO Nuevo->sig = Cab. else { p->sig = Nuevo.

While ( q && item > q->info) reemplazando: 1000 && 'I' > 'B' es verdadero al ser verdadero el While. imaginemos la situación: Cab ┌────┐ │1000│-> └────┘ 1000 ┌─────┐ │ B │ ├─────┤ │2000 │-> └─────┘ p ┌────┐ │1000│ └────┘ 2000 ┌─────┐ │ E │ ├─────┤ │3000 │-> └─────┘ q ┌────┐ │2000│ └────┘ 3000 ┌─────┐ │ G │ ├─────┤ │1500 │-> └─────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │ └─────┘ item ┌────┐ │ I │ └────┘ la 4000 ┌─────┐ │ I │ ├─────┤ │nulo │ └─────┘ Nuevo ┌────┐ │4000│ └────┘ El flujo del programa se dezplaza de nuevo a la instrucción while: While ( q && item > q->info ) 2000 && 'I' > 'E' son verdaderos ambos A continuación avanzan los punteros con las instrucciones p=q. q=q->sig. una vez más el flujo del algoritmo se traslada a: While ( q && item > q -> info ) 3000 && 'I' > 'G' verdaderos ambos. de esta forma p y q avanzarán: 1000 cab ┌─────┐ ┌────┐ │ B │ │1000│-->├─────┤ └────┘ │2000 │-> └─────┘ item ┌────┐ │ I │ └────┘ 2000 3000 1500 ┌─────┐ ┌─────┐ ┌─────┐ │ E │ │ G │ │ N │ ├─────┤ ├─────┤ ├─────┤ │3000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ p q ┌────┐ ┌────┐ │3000│ │1500│ └────┘ └────┘ 4000 ┌─────┐ │ I │ ├─────┤ │nulo │ └─────┘ Nuevo ┌────┐ │4000│ └────┘ nuevamente pasamos arriba al mientras: while ( q && item > q->info ) 1500 && 'I' > 'N' verdadero && falso esta conjunción será falsa 164 . se entrará en su ámbito y se producirá ejecución de las instrucciones p=q. 1000 2000 3000 1500 4000 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ B │ │ E │ │ G │ │ N │ │ I │ │1000│--> ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │ 2000│-> │3000 │->│1500 │->│nulo │ │nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ item p q Nuevo ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ I │ │2000│ │3000│ │4000│ └────┘ └────┘ └────┘ └────┘ q=q->sig.

Nuevo = new (NODO). } quedando la lista enlazada así: cab ┌────┐ │1000│--> └────┘ 1000 ┌─────┐ │ B │ ├─────┤ │ 2000│-> └─────┘ item ┌────┐ │ I │ └────┘ 2000 3000 ┌─────┐ ┌─────┐ │ E │ │ G │ ├─────┤ ├─────┤ │3000 │->│4000 │ └─────┘ └─────┘ p ┌────┐ │3000│ └────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │<└─────┘ q ┌────┐ │1500│ └────┘ 4000 ┌─────┐ │ I │ ├─────┤ │1500 │ └─────┘ Nuevo ┌────┐ │4000│ └────┘ reorganizando nuestro dibujo la abstracción que tenemos de ella es: cab ┌────┐ │1000│--> └────┘ 1000 ┌─────┐ │ B │ ├─────┤ │ 2000│-> └─────┘ 2000 ┌─────┐ │ E │ ├─────┤ │3000 │-> └─────┘ item ┌────┐ │ I │ └────┘ 3000 ┌─────┐ │ G │ ├─────┤ │4000 │-> └─────┘ p ┌────┐ │3000│ └────┘ 4000 ┌─────┐ │ I │ ├─────┤ │1500 │-> └─────┘ nuevo ┌────┐ │4000│ └────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │ └─────┘ q ┌────┐ │1500│ └────┘ Se insertará ahora un item 'A': 5000 ┌─────┐ │ A │ ├─────┤ │nulo │ └─────┘ p nuevo ┌────┐ ┌────┐ │nulo│ │5000│ └────┘ └────┘ nuevo ┌────┐ │5000│ └────┘ item ┌────┐ │ A │ └────┘ p = nulo. Nuevo->sig = nulo. observamos que p apunta al nodo anterior a donde debe quedar el nuevo nodo con info 'I'. por esto nos desplazamos al siguiente else. q = Cab. La siguiente instrucción if(!p) se evaluará como falsa ya que p tiene almacenada la dirección de 3000. y q apunta al nodo que debe quedar después de él. Nuevo->info = item. continuamos en su correspondiente else así: else if (!q) !1500 se evaluara como falso este if es falso debido a qué q almacena el valor de 1500.hemos así llegado a la terminación de la instrucción mientras. Nuevo->sig = q. q ┌────┐ │1000│ └────┘ 165 . y allí se inserta el nuevo nodo con las instrucciones: else{ p->sig = Nuevo.

} 5000 cab ┌─────┐ ┌────┐ │ A │ │5000│-->├─────┤ 1000 ┌─────┐ │ B │ ├─────┤ 2000 ┌─────┐ │ E │ ├─────┤ 3000 ┌─────┐ │ G │ ├─────┤ 4000 ┌─────┐ │ I │ ├─────┤ 1500 ┌─────┐ │ N │ ├─────┤ 166 . Observe que para esto el valor de Cab tiene que cambiar a apuntar al nuevo NODO. hasta que el siguiente while se vuelva falso: while(q && item>q->info){ p = q. Se inserta de primero el Nuevo NODO Nuevo->sig = Cab. q = q->sig.1000 ┌─────┐ │ B │ ├─────┤ │ 2000│-> └─────┘ cab ┌────┐ │1000│--> └────┘ 2000 ┌─────┐ │ E │ ├─────┤ │3000 │-> └─────┘ 3000 ┌─────┐ │ G │ ├─────┤ │4000 │-> └─────┘ 4000 ┌─────┐ │ I │ ├─────┤ │1500 │-> └─────┘ 1500 ┌─────┐ │ N │ ├─────┤ │nulo │ └─────┘ While ( q && item > q->info ) 1000 && 'A' > 'B' Es falso en consecuencia no entra al while. con la clave A. se observa que el nuevo nodo. } y quedando nuestra abstracción así: 5000 1000 2000 3000 4000 1500 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ │5000│-->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p nuevo q item ┌────┐ ┌────┐ ┌────┐ ┌────┐ │nulo│ │5000│ │1000│ │ A │ └────┘ └────┘ └────┘ └────┘ Se inserta ahora un item Q: nuevo ┌────┐ │6000│ └────┘ 6000 ┌─────┐ │ Q │ ├─────┤ │nulo │ └─────┘ Observe de lo explicado antes que los punteros p y q recorrerán las siguientes posiciones. Cab = Nuevo. se sigue en el código: if(!p){ //!NULL es verdadero. debe quedar de primero.

siendo verdadero ya que q apunta a un valor no nulo y 'Q' es mayor a 'G'. 'Q' es mayor que 'A'. q es no nulo y 'Q' es mayor que 'B'.└────┘ p ┌────┐ │nulo│ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ q ┌────┐ │5000│ └────┘ el while(q && item>q->info) es verdadero. por esto se modificarán los valores de p y q: cab ┌────┐ │5000│-> └────┘ 5000 1000 2000 3000 4000 1500 ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ 167 . avanzarán p y q: 5000 1000 2000 3000 4000 1500 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ │5000│-->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p q ┌────┐ ┌────┐ │1000│ │2000│ └────┘ └────┘ nuevamente avanzan p y q al ser el while verdadero. por esto. q es 2000 y 'Q' es mayor que 'E': 5000 1000 2000 3000 4000 1500 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ │5000│-->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p q ┌────┐ ┌────┐ │2000│ │3000│ └────┘ └────┘ se evalúa otra vez el while. p y q avanzarán: 5000 1000 2000 3000 4000 1500 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ │5000│-->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p q ┌────┐ ┌────┐ │5000│ │1000│ └────┘ └────┘ de nuevo el while es verdadero. al entrar al while.

//este if es falso //continúa en este else // es verdadero vemos que el primer if(!p) es falso. secuencialmente en: if(!p){ Nuevo->sig = Cab.p ┌────┐ │3000│ └────┘ q ┌────┐ │4000│ └────┘ volvemos arriba al while. Cab = Nuevo. así: cab 5000 1000 2000 3000 4000 1500 6000 ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ 168 . ya que if(!1500) equivale a if(! verdadero) es falso. } else { if(!q) p->sig = Nuevo. y así se evalúa el if(!q) como if(!NULL) es if(!falso) como verdadero. es verdadero: cab ┌────┐ │5000│-> └────┘ 5000 1000 2000 3000 4000 1500 ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ │1000 │->│2000 │->│3000 │->│4000 │->│1500 │->│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p ┌────┐ │4000│ └────┘ q ┌────┐ │1500│ └────┘ una vez más el while es verdadero. ya que q es igual a nulo. el algoritmo de esta forma continuará. produciendo lo siguiente como abstracción en memoria RAM: 5000 1000 2000 3000 4000 1500 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │ N │ │5000│->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │>│2000 │>│3000 │>│4000 │>│1500 │>│nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ p q ┌────┐ ┌────┐ │1500│ │nulo│ └────┘ └────┘ Al volver arriba al while(q && item>q->info) encontramos que se evaluará como falso. q es diferente de nulo y 'Q' es mayor que 'N'. produciéndose la asignación p->sig = Nuevo. de esta forma continúa en el else. y de esta forma la inserción del nodo con la clave Q en la lista enlazada. q vale 4000 y 'Q' es mayor que 'I'.

y dependerá solo de la conveniencia del caso en particular. Insertemos un item 'E': p = nulo. // Cab está en nulo Nuevo = new (NODO). //se crea un Nuevo NODO Nuevo->sig = nulo. p ┌────┐ │nulo│ └────┘ q ┌────┐ │nulo│ └────┘ nuevo ┌────┐ │2000│ └────┘ 2000 ┌─────┐ │ E │ ├─────┤ │nulo │ └─────┘ cab ┌────┐ │nulo│ └────┘ while(q && item>q->info){ al ser q igual a nulo el While es falso. q = Cab. Insertemos a continuación un nodo cuando la lista simplemente enlazada esté vacía. } la situación en RAM es la siguiente: p ┌────┐ │nulo│ └────┘ q ┌────┐ │nulo│ └────┘ nuevo ┌────┐ │2000│ └────┘ cab ┌────┐ │2000│--> └────┘ 2000 ┌─────┐ │ E │ ├─────┤ │nulo │ └─────┘ De esta forma hemos recorrido las cuatro diferentes casos de inserción de un nuevo nodo: 1. 3. cuando la lista está vacía. 2. verifíquelo a continuación usted mismo insertando otro item 'E'. cuando se inserta al final de la lista simplemente enlazada. Nuevo->info = item. Aunque en nuestro ejemplo no hemos colocado valores a insertar de item repetidos. Cab = Nuevo. 4. ¿Cuál será la abstracción al final? 169 . por esto es verdadero Nuevo->sig = Cab. esto es posible. se continuará el algoritmo en: if(!p){ // se niega algo falso.┌────┐ │5000│ └────┘ │ A │ ├─────┤ │1000 │ └─────┘ │ B │ ├─────┤ │2000 │ └─────┘ │ E │ ├─────┤ │3000 │ └─────┘ │ G │ ├─────┤ │4000 │ └─────┘ │ I │ ├─────┤ │1500 │ └─────┘ │ N │ ├─────┤ │6000 │ └─────┘ │ Q │ ├─────┤ │nulo │ └─────┘ p nuevo q ┌────┐ ┌────┐ ┌────┐ │1500│ │6000│ │nulo│ └────┘ └────┘ └────┘ Aunque debiera haber sido lo primero en explicar. cuando se inserta al inicio de la lista. cuando se inserta en posición intermedia.

hasta el momento: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(2000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │2000 │ │ │ └─────┘ │ └───────────────┘ Las siguientes invocaciones recursivas producirán lo siguiente: ListaInversa(3000) ┌───────────────┐ ListaInversa(4000) ┌───────────────┐ ListaInversa(NULL) ┌───────────────┐ 170 . en memoria RAM imaginemos lo siguiente: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ En esta nueva invocación la instrucción: if(P) P vale 1000 por esto el if es verdadero. en el nodo 1000 el campo sig tiene un valor de 2000. sigue el algoritmo en ListaInversa(P->sig). al invocarse inicialmente └────┘ Se pasa a la instrucción: if(P) es verdadero ya que P vale 5000. por esto se invoca nuevamente ListaInversa pasando el parámetro P->sig con el valor de 2000. sigue el algoritmo en ListaInversa(P->sig). en el nodo 5000 el campo sig tiene un valor de 1000. Cabeza de lista. P apunta al nodo 5000. por esto se invoca recursivamente ListaInversa pasando el perámetro 1000. en memoria RAM. P apunta al nodo 1000.0RECORRIDO RECURSIVO DE UNA LISTA ENLAZADA Estudiemos a continuación la función recursiva ListaInversa: void ListaInversa(NODO *p){ if(p){ ListaInversa(p-sig). } } Para esto supongamos se encuentra en memoria la siguiente lista simplemente enlazada: 5000 1000 2000 3000 4000 cab ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ │ A │ │ B │ │ E │ │ G │ │ I │ │5000│-->├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ └────┘ │1000 │->│2000 │->│3000 │->│4000 │->│Nulo │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ P ┌────┐ │5000│ P recibe este valor. cout << endl << p->info.

de esta forma esta llamada de la función terminará. se terminará la función y quedando ahora en memoria: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(2000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │2000 │ │ │ └─────┘ │ └───────────────┘ estando en la función ListaInversa(2000) se escribirá en pantalla el valor al 171 . para quedar en memoria: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(2000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │2000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(3000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │3000 │ │ │ └─────┘ │ └───────────────┘ estando en la función ListaInversa(3000) se escribirá en pantalla el valor al que apunta P. mostrando en pantalla el caracter 'I'.│ P │ │ ┌─────┐ │ │ │3000 │ │ │ └─────┘ │ └───────────────┘ │ P │ │ ┌─────┐ │ │ │4000 │ │ │ └─────┘ │ └───────────────┘ │ P │ │ ┌─────┐ │ │ │NULL │ │ │ └─────┘ │ └───────────────┘ En esta última invocación la instrucción: if(P) es falsa P vale NULL. el último de la lista y luego terminarse la función. quedando en memoria: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(3000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │3000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(4000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │4000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(2000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │2000 │ │ │ └─────┘ │ └───────────────┘ es decir que a continuación se ejecuta la instrucción de escritura en pantalla: cout << endl << p->info. es decir 'G'. volviendo a la instrucción siguiente donde fué invocada.

que apunta P. se terminará la función y quedando ahora en memoria: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ volvemos ahora a la función ListaInversa(51000) se escribirá en pantalla el valor al que apunta P. Realice función que busqué las personas en el rango de dos estaturas digitadas por teclado. 3.. A la struct INFO agréguele el campo de Altura de la persona. se terminará la función y quedando ahora en memoria: ListaInversa(5000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │5000 │ │ │ └─────┘ │ └───────────────┘ ListaInversa(1000) ┌───────────────┐ │ P │ │ ┌─────┐ │ │ │1000 │ │ │ └─────┘ │ └───────────────┘ volviendo ahora a la función ListaInversa(1000) se escribirá en pantalla el valor al que apunta P. Colóquele un menú de conmutadores y manejo del mouse(es decir debe poder moverse con las flechas las opciones). 5. observandose en pantalla la lista simplemente enlazada en orden contrario. si el promedio de las 10 personas es 34 años y María tiene 20 años y Juan 40. Ver el correspondiente código fuente del la lista simplemente enlazada. María 20 -14. 6... Realice función la cual muestre en pantalla y grabe en archivo de texto. 4. Muestre en pantalla y grabe en archivo de texto(entregármelo en disquete) los registros clasificados por edad 172 .. implementada en memoria din mica y clasificada por una clave en el archivo: LISTADIN. 2. Realice función la cual muestre en pantalla el nombre de la persona que tiene más años y. Mostrar en pantalla y grabar en archivo de texto(Copiarlo en disquete que me entregaran).CPP Ejercicio de Programación: Utilice el programa ListaDin..cpp –anterior. El promedio de las edades es 34 años 7. se terminará la función y volverá el flujo del programa a la instrucción siguiente a la invocación inicial. Juan 40 6 .como herramienta para realizar lo propuesto a continuación: 1. es decir 'E'. es decir 'A'. Efectúe captura de al menos 10 registros. la que tiene menos años. Por ejemplo. es decir 'B'. el archivo binario generado debe entregármelo en un disquete. Efectúe modificaciones por esto en las funciones de captura y de listar. los nombres de cada una de las personas y la diferencia que tienen cada una con la edad promedio de todas. debería aparecer en pantalla((observe el negativo en María): . supongamos que es única en ambos casos. en forma gráfica..

y efectúe conversión forzada. este nodo apuntará a la segunda de menor edad. 9. contestar el enunciado anterior. 10. El algoritmo puede ser una versión de la burbuja pero no en vectores. No utilizar la librería string.) Archivo binario con los. En resumen.cpp (con las funciones que realizó y que corra. Dejar separación adecuada entre funciones. grabarlo en disquete y entregármelo. Las funciones que no lo hagan. 10 registros capturados. insertando en cada caso el código y los resultados correspondientes. 6. Todo el programa ListaDin.h.CPP. *q) con ellos debe ir desplazándose por la lista e ir intercambiando los nodos.Doc. en vez de ella construir una librería que incluya las funciones para manejo de cadenas necesarias. con las modificaciones anteriores. Para esto defina un nuevo puntero Cab2. Similar a la función que graficar barras representando edades(ver ListaDIN. debe recorrer la lista en memoria. De los demás solo quiero que los coloquen por si veo alguna inconsistencia y. Presentar estadísticas adecuadas con la ayuda del programa ESTADIST. Utilizar en algunas funciones paso de parámetros por valor y por referencia a la manera del C con punteros y también del C++ con el operador de dirección &. al menos. con los registros con los que se trabaje. apuntada inicialmente por Cab. Presentar la información adecuadamente tabulada en pantalla. Archivos de texto de las preguntas 5. Es decir este archivo (Segundo Parcial Informática III. en ningún momento en clave o abreviaturas que no se entiendan rápidamente. Presentar niveles de ayuda con la tecla F1 en varias partes del programa.ascendentemente. Muestre en pantalla y archivo de texto(entregármelo en disquete) los registros clasificados por altura ascendentemente. los identificadores que utilice.CPP. cambie ahora a las alturas de las personas(Observe que el cambio es de int a flot. sino directamente sobre la lista enlazada. o similar.Doc) con sus respuestas. Defina al inicio del archivo del programa todos los prototipos de las funciones utilizadas con comentarios que documenten el mismo. marcarlas con comentarios. etcétera. Para calificar solo miraré este archivo. y con los colores que crea más agradables. Entonces debe estar muy bien presentado. de todo su trabajo. Efectúe un informe en archivo de Word. Presentar pulcramente el sangrado de todo el código fuente. e ir insertando en nuevas direcciones de memoria cada uno de los registros de las personas. (cast). En Word. Esta vez efectúe la clasificación cambiando el orden que tiene. Así mismo presente diagramas de barras con variables numéricas adecuadas. 7 y 8( cuatro archivos) En total 7 archivos. Es decir que Cab quedará apuntando al nodo de la persona de menor edad. Truco: convierta cada edad en metros a centímetros multiplicando por 100. entregarme copia de este archivo también. Utilice al menos dos variables de tipo puntero(NODO *p. Pero bueno es un simple ejercicio. La falla de hacerlo así es que cada Nodo quedará dos veces. Debe contestar 173 . Copia de su versión de ListaDin. deben entregarme en un disquete: • • • • • Copia de este archivo con todas las respuestas: Segundo Parcial Informática III. defínalos autodocumentados. de esta forma: AlturaCms = (int) AlturaMetros * 100. donde crea necesario. PROGRAMAS A REALIZAR COMO EJERCICIO de Programación por grupos PARA TODOS LOS GRUPOS: incluir al menos lo siguiente: - - Rehacer enunciado entregado de forma resumida y clara. Presentar los registros clasificados por más de una clave en pantalla y en papel(presente listado físico en papel) Se debe permitir tener la opción de escoger varios tipos de letra para imprimir en papel. Utilizar menúes adecuados de conmutadores horizontales y verticales en los submenús.cpp). 8. ayudarlos a corregirla. Utilizar operaciones de archivo tanto de lectura como de escritura. y colocarle a cada una de ellas su objetivo.

Debe mantener adicionalmente una mariable global para el total de registros actuales. Presentar algoritmo pulcramente con sangrado adecuado en lenguaje C+ +. El programa presentará inicialmente un un menú principal de conmutadores. debe aparecer en pantalla toda su información sobre la matrícula. debe aparecer en pantalla toda su información sobre la matrícula. Los Cargos fijos son de $100.15% de la renta gravable. nombre. TOTAL MATRICULA: submenú que permita presentar en pantalla y escrito en papel. Calcular la cantidad a pagar de matrícula por cada estudiante de la siguiente forma: El total a pagar es igual a los cargos fijos más los cargos variables.doc 1.000. los cargos variables y el total a cancelar por concepto de matrícula. mostrando el listado correspondiente. tomados estos datos de la correspondiente declaración de renta de los acudientes del estudiante. renta. Los Cargos Variables se calculan como un 0. Debe utilizar operaciones de archivo. Digitar un apellido o nombre y a continuación presentar todos los nombres completos de estudiantes que lo contengan.Digitar el código del estudiante y a continuación. totalizando al final. patrimonio. y si existe. En una encuesta de un indeterminado número de jefes de hogar.1 del patrimonio + 0. Para esto utilice los ejemplos de programas dados en:ArchivosBinariosYTexto. Digitar el nombre de un estudiante y a continuación. BUSCAR: se debe presentar un submenú el cual permita invocar sendas funciones las cuales permitan:. a leer inicialmente desde teclado y posteriormente grabar en disco. el cual permita invocar funciones que hagan lo siguiente: CAPTURAR: Leer los campos de cada registro de estudiante por teclado. ESTADISTICA: presentar estadísticas de el total de matrícula. estudiante. y si existe. encontraremos al menos los siguientes campos: código del estudiante. cada vez la correspondiente variable global del número de registros debe incrementarse en uno. por apellido.CPP. y cuarta opción que permita calcular y mostrar el salario promedio por hogar. Presentar listado de el total de matrículas. El listado debe obtener una impresión por impresora de código. Se debe calcular el valor de los cargos fijos. para luego poder ser recuperados del mismo y de esta forma estar disponibles en cualquier momento. ESTADISTICA: Presente submenú con las cuatro opciones siguientes: presentar estadísticas sobre los ingresos mensuales y sobre el pago de renta y el número de hijos. cargos variable y total de matrícula. cargos fijos. patrimonio y renta Representar por medio de nodos de una lista simplemente enlazada los registros que representan la información del estudiante. se les pregunta a cada uno ¿Cuál es su ingreso mensual? ¿Cuál es la renta que paga por su casa de habitación?. En cada registro. con la ayuda del programa ESTADIST. dividiendo la sumatoria de los ingresos mensuales entre el número de jefes 174 . apellido.cada una de las preguntas efectuadas. LISTAR: presentar en pantalla un submenú el cual permita listar la información clasificada por las claves: código del estudiantes. 2.

empero. Efectuar funciones que permitan: CAPTURAR: la captura de estos registros y mantenerlos en memoria en la lista enlazada. renta. acumularlas. PRECIO UNITARIO: A partir de digitar el código de un libro. en pesos. es decir es de lujo el precio calculado hasta el momento se aumentará en un 60%. y si es en rústica o de lujo. si el número de páginas excede de 300. Cierta Universidad está interesada en saber estadísticamente la calificación promedio de los estudiantes que recibieron matemática durante un semestre. con la ayuda del programa ESTADIST. ESTADISTICA: presente estadísticas de el valor de los libros. Mostrar el mismo inventario de libros clasificados por autor. del inventario de libros. Imprimir el total. BUSCAR: Por medio de submenús conteste cada uno de los siguientes interrogantes: Se debe digitar un código de libro y si existe en el inventario decir su precio. Escoja al gusto si prefiere ordenes descendentes o ascendentes. renta. nombre completo del autor.CPP 4. cuántos mayores o igual al mínimo y menores a tres salarios mínimos y cuántos tienen ingresos inferiores al mínimo. titulo y autor. Digitar una palabra y mostrar en pantalla todos los títulos que la contengan. CLASIFICAR: Por medio de submenus clasificar por: código. valor de cada libro. Digitar un valor de renta y mostrar todos los registros que cumplen con que la de ellos en mayo o igual. número de páginas. 3. Digitar un valor de libro y listar a continuación todos los libros que tienen igual o mayor precio. número de hijos y efectuándo ciclo repetitivo capturar la edad de cada uno de sus hijos. para finalmente asignar a campo de edad promedio su respectivo valor. Digitar un apellido o nombre y a continuación presentar todos los nombres completos de autores que lo contengan. Calcular e imprimir el código y el precio para cada uno de los libros. Una editorial tiene un conjunto de registros para cada uno de los títulos de libros existentes. si el número de páginas excede de 550. efectuar su búsqueda y mostrar su precio teniendo en cuanta lo siguiente: El precio básico de un libro es de $2. CAPTURA: leer los campos Cédula jefe de hogar. LISTAR: Por medio de un submenú mostrar en pantalla o en papel lo siguiente. BUSCAR: Submenús que permitan encontrar los ciudadanos que están en cada uno de los rangos de salario mínimo señalados anteriormente. Se debe calcular cúantos hogares tienen ingresos superiores a tres salarios mínimos. el precio sufrirá un recargo adicional de $10. Desea saber también el número total de estudiantes y el número de estudiantes 175 . a partir de una cédula mostrar los datos de la correspondiente persona. título de la obra. Digitar un título de un libro y a continuación decir cuantos ejemplares de ese título hay en existencia en el momento. salario. el precio se incrementará $8. clasificados por el código del libro. más 35 pesos por página. Mostrar tambien clasificado por título. Digitar el nombre de un autor y a continuación mostrar todos los libros que le pertenescan de entre el inventario. Si la edición no es en rústica. LISTADOS: En submenús presente listados promedio de hijos y cédula de identificación.000.de hogar. clasificados por salario. existencia en bodega de cada título. cada uno de los cuales contiene: código del libro. y esto debido al mayor costo de la compaginación y empastado.

Se digita un plan de estudios y a continuación se muestran todos los estudiantes que corresponden a ese plan y su promedio de nota en matemática. con la ayuda del programa ESTADIST. LISTAR: Utilizando submenú listar en pantalla adecuadamente y por impresora en papel utilizando diversas claves de ordenamiento. CAPTURAR: Calcular lo anterior teniendo en cuenta que se leen: la calificación definitiva de matemáticas. y los cuales hay que capturar por teclado. Permitir la impresión en cada oportunidad en papel. Clasificar por medio de la clave nombre de el artículo. LISTAR y CLASIFICAR: Listar por mdio de submenús. y por esto le entregó unos registros con los siguientes datos. también efectúe gráfico de barras. si es que existe.Listado de artículos con existencia menor a la existencia mínima. Una compañía le encarga un informe para comprar mercancía. por plan y en total.Listado de artículos sin existencia en inventario.(Cantidad de reorden). de todos los estudiantes que cursaron matemática. y con la ayuda del programa ESTADIST. en unidades.Existencia mínima en unidades. También grafique diagrama de barras. 6.. nombre del cliente. si es que existe. en matemática. BUSCAR: Utilizar submenús para contestar lo siguiente: 176 .Código del artículo (clave). los cuales debe capturar por teclado y posteriormente mantener en disco:.. valor original de la factura. Mostrar el total del inventario representado en pesos($).Existencia actual en inventario.. ESTADISTICA: presente estadísticas de las calificaciones de matemática.. como clave secundaria.CPP. ESTADISTICA: presente estadísticas de el existencias multiplicadas por el valor unitario de cada artículo. . y mantener adecuadamente actualizados en disco... LISTAR: Debe producir un informe de los artículos que hay que comprar de acuerdo a las siguientes condiciones: . GRABAR Y CARGAR: Todos los registros deben estar en disco.reprobados. BUSCAR: por medio de submenús contestar lo siguiente: Digitar un código de artículo y mostrar la información correspondiente a él.Listado de artículos con existencia superior a un 50% de la existencia mínima. 5. Número de factura.Valor unitario.Cantidad en pesos($) del total de artículos a comprar. código y número de plan. Mantener clasificado por la clave Código de artículo. información clasificada por plan de estudios. Se debe elaborar un informe de cartera con base a una serie de registros con los datos de: código.Nombre del artículo.CPP. La información de los registros debe permanentenete estar clasificada por el número del código de cada uno de los estudiantes. Digitar un nombre de artículo y contestar con su cantidad en inventario. CLASIFICAR: Por medio de submenús. BUSCAR: Se digita un código y a continuación se muestra la nota de el estudiante correspondiente. plazo del crédito para cancelar la obligación. Digitar una palabra y a continuación mostrar todos los nombres de productos que la contienen. y dentro de cada plan de estudios listar clasificado por código de cada estudiante.

y clasificada por el número de placa. Digitar un número de factura y mostrar toda la información disponible y por calcular de la misma.Se debe elaborar un informe a nivel de cliente teniendo en cuenta que si el plazo es hasta de 30 días se liquida 1% de interes. Digitar el nombre de un cliente y a continuación mostrar todas las facturas que tiene pendientes de pago. Digitar un número de placa y mostrar en pantalla el registro de multa correspondiente. número del día del año en que fue hecho el prestamo(del 1 al 365). si el plazo esta entre 30 y 60 días se liquida un 2%. El límite de velocidad en autopista es de 80 kph. ESTADISTICA: presente estadísticas de el total de las facturas. LISTAR: Presentar por medio de submenú las multas de todos los infractores.000 adicionales. Se debe imprimir el valor del interés pagado por cada cliente y el total para todos ellos. Valor del préstamo. Se deben capturar los anteriores datos y mantenerlos tanto en RAM como posteriormente ser almacenados en disco.5%. Por cada kilómetro de exceso se le cobran $3. Este listado debe aparecer clasificado por la clave Cédula. Por cada kilómetro de exceso se le cobran $4. Digitar un tipo de vía y mostrar a continuación todos los registros de multa que coincida con él. Grafique en forma de barras 8. 177 . Velocidad del vehículo infractor. La Secretaría de Tránsito decidió cobrar multas por exceso del límite de velocidad así: Una cantidad de dinero llamada "Multa básica" más la multiplicación del número de kph en exceso sobre el límite de velocidad por un factor dado en la siguiente tabla de tarifas. Tasa de interés convenida en %. si es que existe. tipo de vía. CLASIFICAR: Presentar listados en pantalla y en papel clasificados por tipo de vía. con la ayuda del programa ESTADIST. y para plazos mayores de 120 días se liquida un 3%.CPP 7. El límite de velocidad en calles es de 40 kph. CAPTURAR: Se deben leer los siguientes campos por cada registro de vehículo infractor: Placa del carro. así: - Límite de velocidad de 60 kph en avenidas. si el plazo está entre 60 y 120 días se liquida un 2.CPP.día del prestamo)/360. Presentar tanto en papel como en pantalla. Se desea saber cuántos autos han sobrepasado cada límite en un determinado tiempo de muestreo y cuánto pagan de multa en total. y de velocidad de infracción. Un banco quiere calcular los intereses que tiene que cobrar al final del año a sus clientes con base a los datos de: Cédula y Nombre del cliente. Se deben tener en disco actualizados los registros. ESTADISTICA: presente estadísticas de el total de multas cobradas. con la ayuda del programa ESTADIST. con el plazo correspondiente en días. BUSCAR: Por medio de submenú. Digitar un real que representará kph y a continuación mostrar todos los registros que tengan infracción por este kilometraje y mayor.000 adicionales. placa de carro.000 adicionales. Por cada kilómetro de exceso se le cobran $2. Para el cálculo de los intereses a cancelar al final del año se aplica la siguiente fórmula: Valor intereses es igual al valor prestamo * (interes/100) * (360 .

en forma ascendente y descendente. La Compañía AXZ tiene un registro por cada empleado con: Cédula de identificación. Mostrar la cantidad a cancelar a cada uno de los empleados. CLASIFICAR: Mostrar en pantalla clasificado por cédula de identidad. Digitar dos edades y a continuación mostrar todos los registros que están en el correspondiente intervalo de edades. sexo y de facultad. 178 . horas extras(se cancela 50 adicional sobre el valor regular). con la ayuda del programa ESTADIST. Por cada grupo se desea saber el promedio de horas trabajadas por empleado. Edad. edad.CPP 9.BUSCAR: Por medio de submenú mostrar lo siguiente: Digitando un nombre de cliente debe aparecer el registro correspondiente con la cantidad de intereses a cancelar. CLASIFICAR: utilizando submenú presente listados clasificados por edad. Se digita cédula y de debe mostrar el registro correspondiente si es que existe. CLASIFICAR: utilizando ascendentes y descendentes prestamos. valor ESTADISTICA: presente estadísticas de el total de intereses a cancelar. y Facultad (Psicología. Se desea saber si los nuevos empleados(menos de un año) tienden a trabajar más horas extras que los antiguos. porcentaje de hombres y mujeres por cada facultad y en la Universidad. Comercio). Digitar un sexo y mostrar todos los registros que coinciden con él. los cuales deben capturar y mantener almacenados en disco. incluyendo la cantidad total que hay que cancelar a este empleado. Digitar cédula y de igual forma aparecer en pantalla toda la información del cliente correspondiente. Digitar un nombre de facultad y a continuación digitar todos los registros que la contengan. con la ayuda del programa ESTADIST. meses trabajados en la compañía. LISTAR: Se debe calcular e imprimir en pantalla y en papel: Promedio de edad de los estudiantes. Se desea saber qué cantidad de empleados tienen menos de un año en la compañía. horas regulares trabajadas. submenús por las mostrar en pantalla claves: cédula. Digitar un nombre o apellido y mostrar en pantalla todos los nombres completos de clientes que lo contienen. BUSCAR: Utilizando submenú. los cuales debe capturar y mantener en disco. si es que existe. tasas de interés. Digitar dos edades y a continuación mostrar todos los registros que están en el correspondiente intervalo de edades. LISTAR: Por medio de submenú.CPP 10. cantidad en dinero a cancelar por hora trabajada. ESTADISTICA: presente estadísticas respecto a la edades. de uno a menos de tres años. Sexo(Masculino. nombre clasificaciones cliente. Ingeniería. Femenino). BUSCAR: Digitar un código y a continuación debe aparecer el registro correspondiente de es estudiante. Se requiere condensar algunas estadísticas sobre los estudiantes de la Universidad. Mantener clasificado por el número de cédula al mostrar lo anterior. Para cada registro se tiene: Código. Mantener clasificado por Código de estudiante. de cinco a diez años y más de diez años. edad. de tres a cinco años. Digitar dos enteros que representarán meses y a continuación mostrar todos los registros que están en el correspondiente intervalo de meses. meses de antiguedad en la compañía en ordenes ascendentes y descendentes.

con la ayuda del programa ESTADIST. multiplicado por el costo unitario. 13. edad. BUSCAR: digite un código de almacen y a continuación mostrar todos los registros que lo contengan.CPP 11. con la ayuda del programa ESTADIST. Representar en memoria por medio de una lista enlazada en memoria dinámica. no trabaja) y Cantidad que cancela de matrícula. entradas. PROGRAMA PARA UNA LINEA AEREA: Una línea aérea desea controlar las reservas de vuelo de un avión. soltero). saldo anterior. enlazada. para lo cual los datos deben mantenerse clasificados de esta forma en memoria RAM. Lo mismo para el código del departamento. Cada registro debe tener al menos los siguientes campos: 179 .CPP 12. Digitar nombre de universidad y mostrar a continuación todos los registros de estudiantes que la contienen. BUSCAR: Digitar nombre de estudiante y a continuación mostrar los correspondientes campos del registro correspondiente. Se tienen registros con los datos de la ciudad. Deben darse totales de los valores por cada departamento de almacén. LISTAR: Debe presentarse un listado clasificado por Ciudad como primera clave. Digitar nombre de ciudad y a continuación mostrar todos los registros correspondiente. su total está dado por el saldo anterior más las entradas. Idem para el pago de matrícula. campos estos que deben ser capturados y mantenidos en disco. En un almacén de cadena se tienen unos registros de inventario con los siguientes datos: código del almacén. y Facultad como tercera clave. Una asociación de universidades está interesada en elaborar una relación de estudiantes que sean casados y que trabajen. código del departamento. ESTADISTICA: presente estadísticas de edades de los estudiantes de las universidades.ESTADISTICA: presente estadísticas de el total pagado a cada empleado. los cuales se debe capturar por teclado y mantener adicionalmente en disco. con la ayuda del programa ESTADIST. CLASIFICAR: Mostrar listados por separado clasificados por edad. estado civil(casado. salidas. de almacen y de artículo en forma ascendente y descendente. Universidad como segunda clave. por cada almacén y para toda la cadena. Facultad. habrá un número prefijado de sillas. ESTADISTICA: presente estadísticas de el valor de las mercancías en inventario. código del artículo. Cada registro en la lista representa una silla. este guarismo resultante. CLASIFICAR: Por las claves código de departamente. teniendo en cuenta que para cada item de inventario. situación laboral (trabaja. Universidad. cuando el saldo actual sea inferior al stock mínimo y un aviso de "alerta" cuando el saldo varíe en un 40% por encima del stock mínimo. stock mínimo y costo unitario. y finalmente igual para el código de artículo. LISTAR: Se debe imprimir un informe en donde se muestre por cada registro el valor y cantidad del saldo actual con su stock mínimo y un aviso de "Compra". estado civil y situación laboral. menos las salidas y.CPP. nombre del estudiante. El número de cupos disponible para el vuelo es de MAX sillas.

y otra opción que permita imprimir en papel. las edades de los pasajeros. y se debe dejar marcada como "vacía" en el campo "Estado de la Silla" correspondiente. CERRAR EL VUELO(y terminar el programa): Cuando el avión vaya a despegar. Reservada. imprimirlos en papel. y otro por apellido. producir un listado con la siguiente estadística: • Números de sillas ocupadas y sillas vacías (las vacías son las marcadas como "vacías" más las reservadas que no viajó nadie en ellas). • Estadísticas de ESTADIST. POR FAVOR CIERRE EL VUELO". • Listado de todos los nombres de pasajeros clasificados en orden alfabético. con todos sus datos. el cual permita invocar funciones que hagan lo siguiente: RESERVAR CUPO: En caso de estar llenos los cupos que aparezca el aviso "CUPO COMPLETO.CPP. CANCELAR RESERVA: Se pide al pasajero el número de silla que tiene reservada. En caso de haber disponibilidad se le asigna el número de silla marcando como "Reservada" en el campo "Estado de la silla". inmediatamente en este gráfico.Nombre pasajero. A continuación. cédula. De esta forma el número de reservas se decrementará en una. teléfono. • Los pasajeros que sean de nacionalidad “satanizada” por los Estados Unidos. con su respectivo teléfono y cédula. con la ayuda del programa Todo lo anterior se debe manejar a partir de menús de conmutadores gráficos adecuados y en ventana el dibujo como abstracción de los puestos del avión. Ocupada) Nacionalidad Representar globalmente mediante lista enlazada y variable que cuente las reservas efectuadas. Al iniciar el programa debe inicializar los campos que corresponden al estado de la silla con vacío (podría ser un cero o una letra V). LISTAR: presentar en pantalla un submenú el cual permita listar la información clasificada por: cédula. estado de la silla(Vacía. 180 . De esta forma el número de reservas aumentará en una cada vez que sea invocada esta función. presentar un menú principal de conmutadores. edad. Cada cambio que ocurra en la situación de ls sillas debe observarse. CONFIRMAR RESERVA: Cuando el pasajero se presenta al aeropuerto se le debe solicitar el número de silla(se supondrá que se la sabe) y marcarla como "ocupada".

else como el primero 181 . LISTADOBLE *Encontrar(INFO). }*Cab=NULL.h> //delay() // LISTADOBL. typedef struct NODO NODO. while (q != NULL && item. return(0). #include #include #include #include #include #include <stdio. if ( !(nuevo = new(LISTADOBLE) ) ) { cout << "No hay memoria suficiente". struct INFO{ int Entero. void Eliminar(LISTADOBLE *). if ( !p && !q) // lista esta vac¡a.Entero == q->Info.LD" typedef struct INFO INFO.Entero){ p = q. LISTADOBLE *sig. void ListaDesdeElFinal(). q = Cab. const int BytesReg = sizeof(INFO).h> <ctype. *nuevo. void CargarLista().LISTA DOBLEMENTE ENLAZADA //El siguiente programa implementa una lista doblemente enlazada. nuevo->sig = q.h> <iostream. } nuevo->Info = item.h> <dos. } if (item. p = NULL.CPP #define ARCHIVO "Agenda.Entero > q->Info. char Cadena[25]. q = q->sig. *q. void GrabarLista().h> <fstream. nuevo->ant = p. int Insertar (INFO). LISTADOBLE *ant. void GrabarLista(). void Listar(). el nodo quedar Cab = Fin = nuevo. int Insertar (INFO item){ LISTADOBLE *p. *Fin=NULL.h> <conio. }. struct LISTADOBLE{ INFO Info.Entero) // elemento repetido return 0.

while (p != NULL && item. Cab = nuevo. else{ // caso general. quedando al inicio q->ant = nuevo. q->sig = NULL.if (!p && Cab){ // va antes del primer nodo.Entero == p->Info.Entero) p = p->sig. } } return(1). if (item. else return NULL. while (q->sig != p) q = q->sig. } } delete(p). } void Listar(){ LISTADOBLE *p. // insertado } void Eliminar(LISTADOBLE *p){ LISTADOBLE *q. q->ant = nuevo. } else { p->sig = nuevo. if (p && !q) // el nodo quedar en la última posicion Fin = nuevo. se inserta en medio nuevo->sig = q. Cab->ant = NULL.Entero != p->Info. p = Cab. if (p == Cab){ //eliminar el primer nodo de la lista doblemente enlazada Cab = p->sig.Entero) return p. if (p == Fin){ //Eliminar el £ltimo nodo de la lista doblemente enlazada Fin = q. } else { q = Cab. } else{ //Caso general Eliminar en medio de la lista doblemente enlazada q->sig = p->sig. if (!Cab) cout << "Lista vac¡a \a\n". } LISTADOBLE * Encontrar(INFO item){ LISTADOBLE *p. p->sig->ant = q. else { 182 .

} else { Cab = Fin = NULL. } out. if (!in){ //in es una funci¢n de la clase ios que est en fstream. } } } void ListaDesdeElFinal(){ LISTADOBLE *p.Cadena << " p = p->ant. } } delay(2000).h cout << "No se puede abrir el archivo \a\n".Cadena << " p = p->sig. delay(2000). } } void main(){ char op.Entero << endl.close(). INFO item. else { clrscr(). while (in){ // in ser 0 cuando llegue a EOF in. delay(2000). } void CargarLista(){ //Se supone los datos est n en orden de la clave en disco INFO registro. } p = Cab. p = Fin. Insertar(registro). ifstream in(ARCHIVO). BytesReg ). " << p->Info. while ( p ){ cout << p->Info. if (!out){ //out es una función de la clase ios que est en fstream. LISTADOBLE *p. while ( p ) { out.h cout << "No se puede abrir el archivo \a\n". p = p->sig. " << p->Info. } void GrabarLista(){ LISTADOBLE *p. BytesReg ).read( (unsigned char *)&registro.p = Cab.close(). 183 . return.Entero << endl. if (!Fin) cout << "\n\nLista vac¡a \a\n". ofstream out(ARCHIVO).write( (unsigned char *)&p->Info. while ( p ){ cout << p->Info. } in.

case 'B': cout <<"\nDigite Entero a eliminar: ". delay(2000). delay(2000). cout <<"\nDigite Cadena: ". CargarLista(). Listar(). else{ cout <<"\n\nNO encontrado en lista\a\n". if (p = Encontrar(item)) cout <<"\nEncontrado en lista con Cadena: " << p->Info. switch ( op = toupper( getch() ) ){ case 'I': cout <<"\nDigite entero: ". cin >> item. do{ clrscr(). if ( ! Insertar(item) ){ cout <<"\nRepetido \a\n". GrabarLista(). delay(2000).Cadena. case 'E': cout <<"\nDigite Entero a encontrar: " . gets(item.Cadena). } break. cin >> item.Entero. case 'L': ListaDesdeElFinal().LISTADOBLE Lista. else cout <<"\n\nNO encontrado en lista\a\n". if (p = Encontrar(item)) Eliminar(p). cout <<"\n\nInsertar Borrar Encontrar Lista_Inversa Terminar: ". break. } //switch } while (op != 'T').Entero. cin >> item.Entero. } 184 . } break.

0.0.0.1.0.1.0.0. 1.1.1.0.1. Entrar=13.1.1.0.1.1. 1. int Matriz[Fila][Col]={ 1.0.0.0.1.0.0.0.0.0.1.0.0.0.0.1.0.1. FilaMenu1=450.1. Fila=19.0.1. 1.1. 1.1.0.1.0.0.0.1.1.0.1. Abajo=0.0.0.1.1.0.0.0. 185 .1.1.MaxopH=4.1.1. *Final=NULL.0.0.0.1.0.0. enseñar a agente a recorrer un laberinto.1.1.0.0.1.1.1.0.0.0.1.1.0.0.1.0.0.0.0.1.0.1.0.0.1.1.1.1.0.1.1.h> #include<conio.1.1.0.0.0.0.1.0.0.0.1.1.0.1.1.0.1.0.0.0.0.1.0.h> #include <ConIO.1.1.1.1.1.1.1.1.0.1.1.1. MaxOpV=3.1.0.0.1.0.0.0.0.h> #include<stdlib.1.0.1.0.0.0.0.0.0.1.1.1.1.1.1.0.0.1.1. struct LABERINTO{ struct PuntoXY info .1.0.0.1.0.0.0. 1.1.0.1.0.0.0. Margen=9.0.0.0.0.0.0.1.0.0.0.1.1.1. Alto=22.1.1.0. //************************************************************************** struct PuntoXY{ int x.1.1. 1.1. 1.1.0.0.1.1.1.1.1. MaxOp1=4.1.1.0. Activo=1.1. 1.0.1.0.0.0.0.1.0.1.0.0.1.0.1.1.1.0.1. 1. 1.0.0.0.1.0.0.0.0.1.1 }.1.1.0.1.1.0.1.1.0.1.1.0.1. Abj=80.1.1.0.0.0.0.0.0.1.0. 1.0.0.1. struct LABERINTO *Sig.0.1.0.0.0.1.1.H> //************************************************************************** const int DesActivo=0. 1.1.1.0.1.1. por medio de las teclas del teclado.0.0.0. Der=77.1.0.1.1.0.0.1.1.1.h> #include<ctype.1.0.1.0.0.1. y0=10.0.0.0.0.1. int y.1.0.0.1. 1.1.0.1.1.1.0.1.0.h> #include<graphics.0.1.0.H> //getch().0.0.1.1.0.0.1.1.1.1.1.0.0.0.0.0.0.AGENTE APRENDE A RECORRER LABERINTO /*El siguiente programa permite.1.0.0.0. se utiliza una lista doblemente enlazada.1.1.1.1.1. 1.1.1.1.1.1.1.1.0. #include <dos.0.0.1.0.0.1. Arriba=1.0.0. ESC=27.0.0.0.1.0.0. Col=25.1.1.0.1.0.1. Izq=75.0.1.0.0.1.0.1.1.1.MaxOpH=6.1. Para el almacenamiento de las posiciones de los movimientos. struct LABERINTO *Ant.0.1.1.0.0.0.0.1.0. */ #include<iostream.0.1.0.1.1. Arb=72. 1.0.1. int N=0.0.0. 1.1.0.1.0.0.1.0. Ancho=22.1.1.0.1.1.0.0.1.1. Xo=50. MaxOp=2.1.0.0.1.1.1.1.1.1.0.0.1.0.h> #include<stdio.0.0.0.1.1.0.0.0.1.1.0.0.0.0.1.0.0.0.0.1. 1.0.0.1.0.1.0. } *Cab=NULL. 1.0.1.0.0.1.1.0. }.1.0.0.1.1.1.

LargoCuadro.x. Y1.x. 2=derecho. &entra.sale. int X2. line(X1.char *Cad. y = sale. &sale ).ax = 0x0000.cx. 1=izquierdo.ax ). } //************************************************************************** void MuestraMouse( void ){ union REGS entra.ax = 0x0001. &entra.x.x. int86( 0x33. else setcolor(WHITE). sale. } //************************************************************************** int LeerTeclaXYMouse( int &x.x.x. BotonMouse = sale.x.Y2. entra. int ArbAbj) { setlinestyle(SOLID_LINE. line(X1.int Oprimido){ register int AltoCuadro. return(sale. AltoCuadro=textheight(Cad) + 7.//************************************************************************** // COMIENZAN FUNCIONES PARA EL MANEJO DEL MOUSE CON INTERRUPCION 33 DEL DOS //************************************************************************** int IniciaMouse( int &BotonMouse){ union REGS entra. int86( 0x33.Y1. int86 ( 0x33. int86( 0x33. &entra.NORM_WIDTH). line(X2.4=central.Y1. } //************************************************************************** void Cursor(int X. return ( sale. entra. int Y1.bx). X2.ax = 0x0002.Y2).x. &entra.Y2). if (!Oprimido) { MarcoVentana(X.dx. x = sale. &sale ). LargoCuadro= X + textwidth(Cad) + 7. Y2). } //************************************************************************** void MarcoVentana(int X1.//Bot¢n: 0=no pulsado. EscondeCursorMouse(). HORIZ_DIR.bx.Arriba). entra. X2. } //************************************************************************** void EscondeCursorMouse( void ){ union REGS entra. setcolor(DARKGRAY).sale. X1. if (ArbAbj == Arriba) setcolor(15). line(X1.Y1). sale.0. X2. entra. int &y){ union REGS entra. int Y2.int Y. 186 . if (ArbAbj == Arriba) setcolor(DARKGRAY).ax = 0x0003. &sale).LargoCuadro.Y+AltoCuadro. &sale).1).x. settextstyle(DEFAULT_FONT. else setcolor(DARKGRAY).Y. char c[2].

fillellipse(X-6. setcolor(WHITE). line(X-4. Cursor(X. Cursor(X.Abajo). fillellipse(X+6. BLUE). delay(100). 2). Y-2.y+(Alto-3).y+6.DesActivo).Y+2. line(x+6.c++) if(Matriz[f][c]==1){ Bloque(Xo+c*Ancho.Y.Cad. line(X+4.x+(Ancho-4). } //************************************************************************** void Bloque(int x.y).x+(Ancho-3).x.y+6). } return.Y.x+(Ancho-3). 187 .y+3.Y+5. 2). X-5. setcolor(LIGHTRED). setfillstyle( SOLID_FILL. line(x+3.f<Fila.Y+AltoCuadro.y0+f*Alto. BLACK). c[1] ='\0'. line(x+6. MuestraMouse(). 2.Y. setfillstyle(SOLID_FILL. rectangle(Xo+c*Ancho. Y-8. setcolor(DARKGRAY). fillellipse(X.char *Cad) { Cursor(X.y0+f*Alto).int Y){ int Radio =7. YELLOW). Y-6).c<Col.y+(Alto-4)).1). 2. outtextxy(X+5.6. Radio. c[0] = Cad[0].y+3.y+(Alto-3)). 4). } else if(Matriz[f][c]==0){ setfillstyle(SOLID_FILL. } //************************************************************************** void OVNI(int X.x+Ancho. Radio-1).Cad.Xo+c*Ancho+Ancho. X+5. setcolor(LIGHTMAGENTA).x+Ancho. BLUE).y+Alto). Y-8.} else { MarcoVentana(X. Y-6).LargoCuadro. } //************************************************************************** void DibujarLaberinto(){ int c. Y-8.Y+5.int y){ setfillstyle(1. Y-8.x+6.DesActivo). */ /**************************************************************/ void PulsadoCuadro(int X.y.y+6. line(x.x+3. line(x+3. delay(100). 4).f++) for(c=0. } //************************************************************************** /* Funcion : PulsadoCuadro */ /* Objetivo : Realiza Cursor con una cadena centrada en su */ /* interior y da la sensacion de que se oprime. for(f=0. 3. fillellipse(X-6. 3. line(x+6.int Y.Activo).y. line(x+(Ancho-3).Cad). f. line(x. fillellipse(X.y+(Alto-3)).y+Alto). Y-2.Y.Cad.y+6.y0+f*Alto+Alto). setcolor(RED). bar(x. } outtextxy(X+5.y. fillellipse(X+6. clearviewport().x+(Ancho-6). c).y+3).y+(Alto-6)).Y.

} //************************************************************************** void InsertarEnListaDoble(int x. nuevo->info. setfillstyle(SOLID_FILL. y+(Ancho-16)).x=x. nuevo->info. BLACK).y=y. Final->Sig=nuevo.7*Alto. nosound(). BLACK). x+(Ancho-13). sound(440).delay(10). } else{ nuevo->Ant=Final. switch (c) { case Der: if(Matriz[(y-y0)/Alto][(x-Xo)/Ancho+1]!=1){ setfillstyle(SOLID_FILL. bar(x-9. x+(Ancho-13). if((y-y0)/Alto==8 && (x-Xo)/Ancho==Col-1){ delay(500). bar(x-9.nosound(). delay(100). y+(Ancho-16)). } else sound(2500). x+=Ancho. y = y0+7*Alto. Final=nuevo.y-12. y). nuevo->Sig=NULL. OVNI(x. y-12.int y){ LABERINTO *nuevo. nuevo->Ant=NULL. OVNI(x. nuevo->Sig=NULL. x = Xo+2*Ancho. y+(Ancho-16)). N=0. do{ c = getch(). Final =nuevo. } break. N++. delay(20).f. if(!Cab){ Cab=nuevo. N++. y). 188 . } } //************************************************************************** void EnsenarAlAgenteMoverseEnLaberinto(){ int x=Xo+1. BLACK).y).y). case Izq: if(Matriz[(y-y0)/Alto][(x-Xo)/Ancho-1]!=1){ setfillstyle(SOLID_FILL. *p. bar(x-9. if (c == 0 ) { c = getch(). y-12.y). nuevo= new LABERINTO. y=y0+1.5*Ancho. sound(1500). x+(Ancho-13). OVNI(x. InsertarEnListaDoble(x. int c. InsertarEnListaDoble(x.

nosound(). y-=Alto. p=Cab.delay(10). sound(2500). sound(2500).y).y). sound(15). setfillstyle(SOLID_FILL.*q. default: sound(440).y+(Ancho-16)).delay(10). sound(2500). BLACK). InsertarEnListaDoble(x. sound(15). } } } while (c!=27).x+(Alto-13). case Abj: if(Matriz[(y-y0)/Alto+1][(x-Xo)/Ancho]!=1){ setfillstyle(SOLID_FILL. y-12. 189 .4).q->info.nosound(). case Arb: if(Matriz[(y-y0)/Alto-1][(x-Xo)/Ancho]!=1){ setfillstyle(SOLID_FILL. N++. delay(10).delay(5).delay(20).nosound(). y+(Alto-16)). BLACK).nosound().p->info. N++. y).4.y-12 .nosound().delay(10). sound(1500). sound(15).14). bar(q->info.delay(20). q=NULL. nosound(). sound(2500). bar(x-9. q->info. } break.x+(Ancho-13). fillellipse(q->info. sound(1500). OVNI(x.q->info.delay(5). bar(x-9.delay(5). } break. setfillstyle(SOLID_FILL. sound(15).nosound().x.y). y). y+(Alto-16)). q->info. } break. sound(1500). InsertarEnListaDoble(x. sound(2500). } //************************************************************************** void ListarHaciaAdelante(){ LABERINTO *p.nosound().y-4.x-=Ancho. x+(Alto-13).delay(10).delay(10). sound(2500). y). y+=Alto.delay(10). OVNI(p->info.x-9. OVNI(x.y).y-12. while(p){ q=p. p=p->Sig. OVNI(x.delay(5).delay(5). sound(2500).delay(10). sound(1500). N++.nosound(). BLACK).delay(5).delay(10). InsertarEnListaDoble(x.x. sound(2500).

DibujarLaberinto().y).nosound().delay(5).Activo). p=p->Ant. q->info. Invocar=1. TotalAnchoCaracteres=0. } Cursor(PosX[pos].nosound(). PosX[0] = (getmaxx()-TotalAnchoCaracteres)/2. pos=0. for(i=0. if (c == 0) { c = getch(). FilaMenu1.nosound(). TeclaMouse=0.x+(Ancho-13).delay(5). sound(1500).sound(1500). BLACK). } } //************************************************************************** void main(){ int i. setbkcolor(LIGHTGRAY).y-12 .x.){ if(Invocar){ for (i=0. switch (c) { case Der: Cursor(PosX[pos]. sound(1350). } while (!kbhit() && !TeclaMouse). bar(q->info. FilaMenu1. char *Opcion[MaxOp1] = {"Ense¤ar". int PosX[MaxOp1].*q. Invocar=0.i<MaxOp1. for(..p->info. } MuestraMouse(). p=Final.i++) TotalAnchoCaracteres += textwidth(Opcion[i])+Margen. Opcion[pos].y). y.DesActivo).x-9. c. sound(1150).delay(10).delay(10). Opcion[i]. if(!TeclaMouse){ c = getch().delay(5). i<MaxOp1.sound(1150). i++){ Cursor(PosX[i]. while(p){ q=p.delay(100). "\\tc\\bgi" ). setfillstyle(SOLID_FILL. initgraph( &ManejadorGrafico."Revez".delay(10). &ModoGrafico."Salir"}. for(i=1. sound(3500)."Auto".q->info. x. OVNI(p->info. do{ TeclaMouse = LeerTeclaXYMouse(x. q->info. q=NULL.nosound().sound(1350). ModoGrafico.y+(Ancho-16)). FilaMenu1.delay(10).i++) PosX[i]=PosX[i-1]+textwidth(Opcion[i-1])+Margen. delay(100).sound(3500).i<MaxOp1.delay(5). 190 . } } //************************************************************************** void ListarHaciaAtras(){ LABERINTO *p. int ManejadorGrafico = DETECT.

while( c!=Opcion[i][0] && i<MaxOp1) i++. Cursor(PosX[pos]. if(i<MaxOp1){ // Se hizo "click" en recuadro del menaú pos=i.Activo). Invocar=1. Cursor(PosX[pos]. Cursor(PosX[pos].Opcion[pos].Opcion[pos]. case 45: return. } } if(Invocar){ PulsadoCuadro(PosX[pos].Opcion[pos]). break.FilaMenu1. break.FilaMenu1.Activo). case 1 : ListarHaciaAdelante(). } else TeclaMouse=0.DesActivo). case 2 : ListarHaciaAtras().FilaMenu1.FilaMenu1. Invocar=1. while(i<MaxOp1 && !(x>PosX[i] && x< PosX[i]+textwidth(Opcion[i])+10) ) i++.FilaMenu1. Opcion[pos]. if (pos == -1) pos = MaxOp-1. pos++.break. Opcion[pos].Opcion[pos]. i=0.FilaMenu1. } } else{ //Se digit¢ tecla en el mouse if(y>=FilaMenu1 && y<=FilaMenu1+textheight("H")+Margen){ Cursor(PosX[pos]. c=toupper(c). switch (pos){ case 0 : EnsenarAlAgenteMoverseEnLaberinto(). i=0.break. pos--. Opcion[pos]. if(i<MaxOp1){// Se digit¢ letra inicial de opci¢n pos = i. case Izq: Cursor(PosX[pos]. if (pos == MaxOp1) pos=0.DesActivo). //Alt-X } } else { if(c==ESC) return.Activo).break.DesActivo). case 3 : return. } } } } 191 . } if (c==Entrar ) Invocar = 1.

192 .

H> #include <CType. tendremos los pacientes de cada uno de los médicos. }. LISTA LISTA. // del paciente char Telefono[10]. con información de Nombre Paciente. typedef typedef typedef typedef struct struct struct struct INFOLISTA INFOLISTA.h> #include <ConIO.h> #include <String. InfoSubLista InfoSubLista. struct LISTA{ INFOMEDICO Info. 193 .Dr". En cada uno de los nodos de la lista principal. *nuevo.h> #include <IOManip. struct InfoCitas{ char Horario[20].h> #include <DOS. Teléfono y Honorarios por hora. Horario de su cita y su teléfono.LISTA DE LISTAS /*El siguiente algoritmo implementa una lista simplemente enlazada en la cual de cada uno de sus nodos se puede desprender una sublista simplemente enlazada. SubLista *Cab.h> #include <StdIO. En cada una de las sublistas que se pueden desprender de los nodos anteriores. char Nombre[25]. }.h> #include <FStream. LISTA *InsertarLISTA (INFOMEDICO item){ LISTA *p. }. SubLista *Sig. *q. SubLista SubLista. } *CAB=NULL.CPP #include <IOStream. fstream Archivo. */ //LISTALIST.H> char NombreArch[20] = "Citas. //permite hasta 24 caracteres char Telefono[10]. struct SubLista{ InfoCitas Info.//Apunta a cada sublista desde cada nodo de la lista principal LISTA *Sig. tenemos la información de un médico: Nombre. float ValorHora. struct INFOMEDICO{ char Nombre[25].

q = CAB. q = q->Sig. while (q->Sig != p) q = q->Sig. while (p && strcmp(item. } delete(p). // No encontrado return p. //"caso general" return(nuevo).p->Info. // No insertado } p = NULL. return 1.Nombre. if(p && strcmp(item. nuevo->Sig = q. p = CAB. if ( nuevo == NULL ) { cout << "No hay memoria suficiente". //eliminado el primer LISTA de la lista else { q = CAB.p->Info.Nombre.Nombre. //era el primero de la lista else p->Sig = nuevo. if (p == CAB) CAB = p->Sig. } LISTA* EncontrarLISTA(INFOMEDICO item){ LISTA *p.Nombre. } 194 . } if (q && strcmp(item. } nuevo->Info = item. return(NULL). return (NULL). while (q != NULL && strcmp(item. q->Sig = p->Sig. if ( p == NULL) CAB = nuevo.Nombre)>0) p = p->Sig. q->Info. // insertado } int EliminarLISTA(LISTA *p){ LISTA *q. nuevo->Cab = NULL.Nombre)>0){ p = q.nuevo = new(LISTA). q->Info.Nombre)!=0 ) p= NULL. //repetido.Nombre)==0){ delete(nuevo).

Nombre). } } } void EncontrarEnLISTA(){ INFOMEDICO item. 195 . } } void BorrarLISTA(){ INFOMEDICO item. cin >> item.ValorHora. getch(). int i=0. else { LISTA *p = CAB.Telefono << setiosflags(ios::right | ios::showpoint | ios::fixed) << setprecision(2) << setw(15) << p->Info. if ( InsertarLISTA(item) == 0 ){ cout << "\n\nRepetido \a". LISTA *p. getch().Nombre << setiosflags(ios::right) << setw(3) << p->Info. cout << "\n\nDigite Info a InsertarLISTA: ". gets(item.void ListarLISTA(){ if (!CAB) cout << "Lista vac¡a \a". else{ cout << "\n\nDigite Nombre del m‚dico a borrar: ". cout << "\n\nTel‚fono: ". if (LISTA) EliminarLISTA(LISTA). cin >> item. cout << "\n\Nombre del m‚dico: ". LISTA = EncontrarLISTA(item). if (CAB == NULL) cout << "Lista vac¡a \a". p = p->Sig. else { cout << "\n\nNo encontrado en lista". LISTA *LISTA. } } } void CapturarLISTA(){ INFOMEDICO item.ValorHora << endl.Nombre). gets(item.Telefono. while ( p ){ cout << setiosflags(ios::right) << setw(8) << i++ << " " << setiosflags(ios::left) << setw(25) << p->Info. if (CAB == NULL) cout << "Lista vac¡a \a". cout << "\n\nHonorarios por hora: ".

} SubLista *EliminarEnSubLista(SubLista *p. } nuevo->Info = item. while (p && strcmp(item.Telefono. //eliminado el primer nodo de la lista else { q = Cab. q = q->Sig. *nuevo.p->Info. while (q->Sig != p) q = q->Sig. if (p = EncontrarLISTA(item)) cout << "\n\nEncontrado en lista y tiene el tel‚fono " << p->Info. q->Sig = p->Sig. } SubLista* EncontrarEnSubLista(InfoCitas item.Nombre.else{ cout << "\n\nDigite Nombre del m‚dico a encontrar: ".Nombre. q = Cab. p = Cab. SubLista *Cab){ SubLista *p. while (q != NULL && strcmp(item. else cout << "\n\nNo encontrado en lista". } getch(). } // =========================================================================== // A CONTINUACION LAS FUNCIONES PARA MANEJAR CADA SubLista // =========================================================================== SubLista *InsertarEnSubLista (InfoCitas item.Nombre)>0){ p = q. if (p == Cab) Cab = p->Sig. //"caso general" return(Cab). SubLista *Cab){ SubLista *p. } delete(p). nuevo->Sig = q. *q. q->Info. } p = NULL. if ( (nuevo = new SubLista ) == NULL ){ cout << "No hay memoria suficiente". return NULL.Nombre)>0) 196 .Nombre). //era el primero de la lista else p->Sig = nuevo. SubLista *Cab){ SubLista *q. return Cab. if ( p == NULL) Cab = nuevo. gets(item.

gets(item.Nombre). gets(item.Nombre). else { cout << "\n\nNo encontrado en lista". cout << setw(15) <<p->Info.Nombre)!=0) p=NULL. if ( !Cab ){ cout << "\n\nNo se pudo insertar: se lleno la memoria\a". cout << "\n\nDigite datos del paciente a insertar: ". p = p->Sig.Telefono.Nombre. getch().Horario). } return Cab. return p.setf(ios::left). while ( p ){ cout. } SubLista* BorrarSubLista(SubLista *Cab){ InfoCitas item. } void ListarSubLista(SubLista *Cab){ SubLista *p. cout << "\n\Horario de la cita: ".Nombre. 197 . cout << "\n\nTelefono: ".Telefono. SubLista *Nodo. Cab). Cab). else{ cout << "\n\nDigite Nombre de paciente a borrar su cita: ".p = p->Sig. Cab). if (!Cab) cout << "No tiene citas \a\n". if (Nodo) Cab = EliminarEnSubLista(Nodo.p->Info. cout << "\n\Nombre: ". } } } SubLista *CapturarSubLista(SubLista *Cab){ InfoCitas item. cout << setw(20) <<p->Info. if (Cab == NULL) cout << "Lista vac¡a \a". gets(item.Horario << endl. cin >> item. int Cliente=0. if (p && strcmp(item. else { p = Cab. cout << setw(2) << ++Cliente << ": " << setw(25) <<p->Info. Cab = InsertarEnSubLista(item. Nodo = EncontrarEnSubLista(item.

break. else{ cout << "\n\nDigite Nombre de paciente a encontrar: ". } void SubListaEnlazada(){ char op. cout << "Estos son los pacienticos de " << q->Info. SubLista *p. INFOMEDICO item. } //=========================================================================== 198 . if (Cab == NULL) cout << "Lista vac¡a \a". q = CAB. if (!q) cout << "No se encuentra ninguna persona de Nombre " << item. break. } void EncuentraSubLista(SubLista *Cab){ InfoCitas item.Nombre. while (q && strcmp(item. switch (op){ case 'I': q->Cab=CapturarSubLista(q->Cab). case 'E': EncuentraSubLista(q->Cab). } } return Cab. else{ do{ clrscr().Nombre. } //switch } while (op != 'T'). } } else cout << "Lista de m‚dicos vac¡a\a". Cab)) cout << "\n\nEncontrado en lista y tiene el tel‚fono " << p->Info.Nombre << endl. op = toupper(getch()). cin >> item.Nombre)!=0) q = q->Sig. case 'B': q->Cab=BorrarSubLista(q->Cab).getch(). else cout << "\n\nNo encontrado en lista". if(CAB){ clrscr(). cout <<"Nombre del Médico a encontrar y colocarle las citas: ". cout << "\nMENU DE SUBLISTA: Insertar Borrar Encontrar Terminar: ".Telefono. q->Info.Nombre. } getch(). if (p=EncontrarEnSubLista(item. LISTA *q. ListarSubLista(q->Cab). gets(item. break.Nombre).

p=p->Sig. } } void CargarLISTA_y_SubListas(){ INFOMEDICO registro. sizeof(n)). SubLista *Cab. int n.write((char *)&p->Info. } GrabarLISTA_y_SubListas(P->Sig).read( (char *)&registro. p->Cab). } } void Grabar(){ Archivo.ios::in|ios::binary). n = 0.open(NombreArch. sizeof(P->Info)). while(p) { Archivo.close(). sizeof(n) ). i++){ Archivo. InfoCitas reg. p->Cab = InsertarEnSubLista(reg. for(int i=0. } } Archivo.open(NombreArch. if (!Archivo) cout << "Error en la apertura del archivo \a". } } void main(){ 199 . Archivo.write((char *)&n.read( (char *)&n. // funcion recursiva if ( P ) { Archivo. //n es el número de nodos en lista enlazada p->Cab=NULL. i<n. while(p) { n++.write((char *)&P->Info. CAB = NULL. p=p->Sig.close(). } //Cuenta # nodos en lista enlazada Archivo. p = P->Cab. Archivo. LISTA *p. sizeof(registro) ) ){ p = InsertarLISTA(registro). sizeof(p->Info)). if (!Archivo){ cout << "No se puede abrir el archivo \a\n".void GrabarLISTA_y_SubListas(LISTA *P){ SubLista *p. else{ GrabarLISTA_y_SubListas(CAB). //Graba en disco # nodos p = P->Cab. ios::out|ios::binary|ios::trunc). } else { while( Archivo. sizeof(reg) ).read( (char *)&reg. int n. //p es puntero a donde se inserto en lista Archivo.

case 'e': . case 'E': EncontrarEnLISTA(). case 'M': CapturarLISTA(). } } while (!(op == 'T' || op == 't' )). case 'b': . } 200 . ListarLISTA(). case 'B': BorrarLISTA(). break. switch ( op = getch() ){ case 'm': . unlink(NombreArch). CargarLISTA_y_SubListas(). case 'c': . //Habilite si quiere borrar NombreArch clrscr(). Grabar(). do{ clrscr(). case 'C': SubListaEnlazada(). break. cout<<"\n\nMENU PRINCIPAL:Medicos Borrar Encontrar Citas Terminar:". break.char op. break.

Ocupa cada uno de ellos un Byte de memoria. 32 42 * 52 4 62 > 72 H 82 R 92 \ 102 f 112 p 122 z 132 ä 142 Ä 152 _ 162 ó 172 ¼ 182 ╢ 192 └ 202 ╩ 212 ╘ 222 ▐ 232 F 242 ³ 252 _ 33 43 53 63 73 83 93 103 113 123 133 143 153 163 173 183 193 203 213 223 233 243 253 ! + 5 ? I S ] g q { à Å Ö ú ¡ ╖ ┴ ╦ ╒ ▀ Q ú ² 34 44 54 64 74 84 94 104 114 124 134 144 154 164 174 184 194 204 214 224 234 244 254 " . es decir ocho bit. 60 < 61 = 68 D 69 E 70 F 71 G 78 N 79 O 80 P 81 Q 88 X 89 Y 90 Z 91 [ 98 b 99 c 100 d 101 e 108 l 109 m 110 n 111 o 118 v 119 w 120 x 121 y 128 Ç 129 ü 130 é 131 â 138 è 139 ï 140 î 141 ì 148 ö 149 ò 150 û 151 ù 158 _ 159 ¦ 160 á 161 í 168 ¿ 169 _ 170 ¬ 171 ½ 178 ▓ 179 │ 180 ┤ 181 ╡ 188 ╝ 189 ╜ 190 ╛ 191 ┐ 198 ╞ 199 ╟ 200 ╚ 201 ╔ 208 ╨ 209 ╤ 210 ╥ 211 ╙ 218 ┌ 219 █ 220 ▄ 221 ▌ 228 S 229 s 230 m 231 t 238 e 239 Ç 240 º 241 ± 248 ° 249 × 250 × 251 Ö 201 . 8 B L V ` j t ~ ê Æ ú ª ░ ║ ─ ╬ ╪ G ¥ ¸ 37 47 57 67 77 87 97 107 117 127 137 147 157 167 177 187 197 207 217 227 237 247 % / 9 C M W a k u ë ô ¥ º ▒ ╗ ┼ ╧ ┘ p f » 38 & 39 ' 40 ( 41 ) 48 0 49 1 50 2 51 3 58 : 59 . numerados del 0 al 255. 6 @ J T ^ h r | å É Ü ñ « ╕ ┬ ╠ ╓ a W ó n 35 45 55 65 75 85 95 105 115 125 135 145 155 165 175 185 195 205 215 225 235 245 255 # 7 A K U _ i s } ç æ o Ñ » ╣ ├ ═ ╫ ß d õ 36 46 56 66 76 86 96 106 116 126 136 146 156 166 176 186 196 206 216 226 236 246 $ .EL CÓDIGO ASCII El código ASCII(American Standard Committed for Information Interchange). y caracteres imprimibles. es el código con el cual operan los microcomputadores que trabajan bajo el sistema operativo MS-DOS y Windows. Tabla de Caracteres ASCII imprimibles. Se compone de un conjunto de caracteres de control.

supongamos el usuario hasta aquí digita ALT M. veamoslo con un pequeño fragmento en C: cout << "digite Combinación de teclas: ". para evitar que nos escriba en pantalla el ASCII correspondiente al 50 Teclas que producen códigos extendidos al digitarlas solas: HOME FLECHA ARRIBA PAGE UP FLECHA IZQUIERDA FLECHA DERECHA END FLECHA ABAJO PAGE DOWN INSERT DELET F1 al F10 F11 F12 0 0 0 0 0 0 0 0 0 0 0 0 0 71 72 73 75 77 79 80 81 82 83 59 al 0 68 133 134 Códigos extendidos de teclas al pulsarlas simultáneamente con la tecla de cambio SHIFT: SHIFT A a la Z F1 al F10 F11 F12 65 al 90 0 84 al 0 93 0 135 0 136 202 . c = getch().A continuación se presentán los códigos de exploración de varias teclas y combinación de teclas. Las combinaciones de teclas o teclas las cuales tienen un 0 en primer lugar en realidad producen dos códigos los cuales deben ser leídos adecuadamente. el cual se conserva en el buffer del teclado: siguiente o código c = getch(). sino es leído con otra instrucción de lectura. él 50 se perderá. (int). Para leer el código extendido. por ejemplo al pulsar simultáneamente las teclas ALT y M se produce un código 0 el cual es leído inicialmente y el siguiente código 50 es dejado en el buffer de memoria del teclado. se coloca el reforzador de tipo. se presentará el valor de 0. para ver que quedó en c: cout << " la variable c tiene el valor de " << c. cout << " el código extendido es " << (int) c.

. casta inferior elocuenciada de impotencia-.... macuqueros.. . abderitanos. ' ` \ Z X C V B N 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 14 16 17 18 19 20 21 22 23 24 25 28 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 M .. Toda aquésa gentuza verborrágica -trujamanes de feria.. .A continuación los códigos extendidos de teclas simultáneamente con las teclas CTRL y ALT respectivamente: CTRL A ... -busca el espíritú mejores aires.. gelasmo me ocaciona: mejores aires. engibacaires.. mejores aires. gansos del capitolio.. " 203 .F10 1 2 3 4 5 6 7 8 9 0 = F11 F12 HOME FLECHA ARRIBA PAGE UP FLECHA IZQUIERDA FLECHA DERECHA END FLECHA ABAJO PAGE DOWN INSERT DELETE TAB ENTER 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 51 52 53 104-113 120 121 122 123 124 125 126 127 128 129 130 131 139 140 151 152 153 155 157 159 160 161 162 163 165 166 ”. busca el espíritu mejores aires-. Después de tántas y de tan pequeñas cosas.. / F1. 0 103 0 115 0 116 0 117 0 118 0 119 0 132 0 137 0 138 0 141 0 142 0 144 0 145 0 146 0 147 0 149 0 150 al ser pulsadas ALT ESC RETROCESO Q W E R T Y U I O P ENTER A S D F G H J K L . Y F1 . F10 IZQUIERDA DERECHA END PAGE DOWN HOME PAGE UP F11 F12 ARRIBA + ABAJO INSERT DELETE / * ALT 1 . 25 0 94 . bascas me suscita.. casta inferior desglandulada de potencia. -busca. toda aquésa gentuza vervorrágica me causa hastío.

"RELATO DE GAZPAR" en "LIBRO DE RELATOS". LEON DE GREIFF Primera Parte Segunda Parte Tercera Parte 204 .

Sign up to vote on this title
UsefulNot useful