You are on page 1of 12

Estructuras de Datos en C++

Metodologa
Usted deber leer el presente documento e ir corriendo los programas en
C++, cuidando de leer bien las instrucciones y tratar de entenderlas por
completo. Est escrito de una forma escalonada para que alcance el
conocimiento de C++ y programacin por objetos de forma progresiva.
Se recomiendo leerlo con cuidado, porque aunque no es demasiado
extenso si contiene mucha informacin que usted debe ir asimilando. Si
va muy rpido llegar un punto en que no entender.
Resuelva los ejercicios y presntelos al profesor.

Ejercicio para Resolver No. 1

Cree una clase que implemente el ejercicio de las palabras homnimas


en una clase pero adems que sea insensible a maysculas, minsculas
y tildes.

Principales estructuras de datos en C y C++


Las principales estructuras de datos que son la lista, la pila, la cola y el
rbol pueden ser implementados en C++, y darles una modularidad que
con lenguaje C no era posible.
Para definir una estructura de datos normalmente se crea un objeto que
maneja la cabeza de la estructura y a travs de los mtodos miembro se
realizan las funciones propias de un TAD.
La estructura ms sencilla es una pila, vamos a crear una pila que
maneje valores enteros. Esta estructura puede implementarse de dos
maneras, una es usando un vector otra usando nodos unidos a travs de
apuntadores.

Vamos a realizar primero una pila hecha con un arreglo esttico (sin
apuntadores) y luego un ejemplo con apuntadores.

Uso de Clases con Arreglos


Las clases nos pueden ayudar a mejorar el manejo de un arreglo. De la
siguiente forma.
prog1
#include "iostream.h"
class Vector {
int vector[50];
public:
Vector();
void entrarDato (int valor, int posicion) {
vector[posicion] = valor;
}
int verDato (int posicion) {
return vector[posicion];
}
void mostrarVector();
};
Vector::Vector() {
for (int i=0; i<50; i++)
vector[i] = -1;
}
void Vector::mostrarVector() {
for (int i=0; i<50; i++)
cout << "vector [" << i << "] = " << vector[i] << endl;
cout << endl;

main() {
Vector mivector;
mivector.entrarDato(345,43);

mivector.entrarDato(23,47);
mivector.entrarDato(5,35);
mivector.entrarDato(8,38);
mivector.entrarDato(10,39);
mivector.entrarDato(23,40);
mivector.mostrarVector();
cout << "********************" << endl;
cout << "Posicion 23 : " << mivector.verDato(23) << endl;

Se puede observar que el manejo desde el main se hace mucho ms


sencillo. Se crea la variable que en este caso se llama mivector y luego
se usan sus mtodos de entrarDato, verDato y mostrarVector, de manera
muy sencilla.

Ejercicio Resuelto A

Haga una clase que contenga un vector de 10, que contenga los
factoriales de los primeros 10 nmeros. Estos valores deben ser
calculados y guardados en el constructor de la clase y luego para
consulta no se deben calcular sino leer del vector interno. Si el usuario da
un nmero mayor a 9 se le informar que no es posible hacer su
operacin.
Elabore la clase y el programa que permita probar su funcionamiento.
Solucin

prog2
#include "iostream.h"
class Factorial {
int vector[10];
public:
Factorial ();
int verFactorial(int dato) {
if (dato < 10)
return vector[dato];
else {
cout << "El valor de " << dato << " no esta presente" << endl;
return -1;

}
}
};
Factorial::Factorial() {
int i,prodacumulado=1;
for (i = 0; i<10; i++)
if (i == 0)
vector[i] = 1;
else {
prodacumulado *= i;
vector[i] = prodacumulado;
}
}
main () {
cout << "Bienvenido al programa factorial" << endl;
Factorial miFactorial;
cout << "5! = "<< miFactorial.verFactorial(5) << endl;
cout << "9! = "<< miFactorial.verFactorial(9) << endl;
cout << "2! = "<< miFactorial.verFactorial(2) << endl;
cout << "1! = "<< miFactorial.verFactorial(1) << endl;
cout << "15! = "<< miFactorial.verFactorial(15) << endl;
}

Pila con Arreglo de enteros


Vamos a crear una clase llamada Pila que manejar una estructura de
este tipo a travs de una clase. La definicin inicial ser as:
#include "iostream.h"
class Pila {
int vector[50];
public:
Pila() { }
}

Pero en este caso al crear este objeto no hace nada porque el


constructor est vaco y no hay forma de llegar a su vector interno.

Las estructuras tienen funciones que se agrupan funcionalmente de la


siguiente forma.
Constructores
Destructores
Funciones analizadoras: que permiten observar los datos
Funciones modificadoras: que modifican la estructura
Para una pila entonces deberemos tener un constructor, funciones de
anlisis (mostrarDatos,verPrimerValor), y modificadoras
(entrarDato,sacarDato). Como no usaremos apuntadores la funcin
destructora no ser necesaria.
Es necesario recordar que en la pila el dato que sale fue el ltimo que se
metio en la estructura.
Para la pila se usar un vector esttico de 50 posiciones y un ndice que
se encargar de indicar donde est la cabeza de la pila. Cuando
indicePila sea -1, la pila estar vaca. Cuando sea 0, indicar que en la
pila hay un dato en la posicin 0, y as sucesivamente.
La clase que podr manejar la estructura de pila es la siguiente:
prog3
#include "iostream.h"
// Pila hecha con un vector fijo de 50 posiciones
class Pila {
int vector[50];
// indicePila:

-1 -> pila vacia

0 -> posicion del dato

int indicePila;
public:
Pila() {

indicePila = -1; }; // constructor

// funciones analizadoras
void mostrarDatos();
int cuantosDatos();
// funciones modificadoras
void entrarDato(int dato);

int sacarDato();
};
// Esta funcin sale del cuerpo de la clase porque usa un ciclo.
void Pila::mostrarDatos() {
cout << endl << "DATOS EN LA PILA" << endl;
for (int i=0; i<=indicePila; i++)
cout << "Dato No. " << i << " : " << vector[i] << endl;
cout << endl;
}
int Pila::cuantosDatos() {
return indicePila + 1;

void Pila::entrarDato(int dato) {


if (indicePila < 49) {
indicePila ++;
vector[indicePila] = dato;
} else
cout << "Pila desbordada: no se aadio valor" << endl;
}
int Pila::sacarDato() {
if (indicePila > -1) {
indicePila --;
return vector[indicePila + 1];
}
return -1;

Hay que notar que todas las funciones con excepcin del constructor se
sacaron del cuerpo de la clase y su nombre se resolvi usando los dos
pares de dos puntos ::. Esto permite implementar una funcin miembro
por fuera del cuerpo de la clase.
De esta forma por ejemplo, la funcin que dentro del cuerpo de la clase
se llama:
void entrarDato(int dato);

Afuera del cuerpo de la clase se llama


void Pila::entrarDato(int dato) {

Esa es la misma funcin solo que el primero es el prototipo que se le


pasa a la clase para que sepa que hay una funcin con ese nombre que
ser implementada ms adelante.
Ahora hace falta un cuerpo del programa o main que sepa como manejar
esta estructura. Para eso implementaremos una funcin men que se
encargar de pedir al usuario que indique cual funcin desea ejecutar,
usando una estructura while.
Se ha creado una funcin adicional que maneja el men:
prog3 (2a parte)
int menu() {
cout << endl << endl;
cout << "Bienvenido al programa manejador de Pila de enteros" << endl;
cout << "Escoja una opcin" << endl;
cout << "**************************************" << endl;
cout << "0. Salir del Programa" << endl;
cout << "1. Adicionar entero" << endl;
cout << "2. Sacar entero" << endl;
cout << "3. Ver cuantos datos tiene la pila" << endl;
cout << "4. Mostrar datos en la pila" << endl;
cout << "**************************************" << endl;
int opcion;
cin >> opcion;
return opcion;
}
main () {
Pila pila1;
int respuesta,opcion;
opcion = -1;
while (opcion != 0) {
opcion = menu();
switch (opcion) {
case 0:
cout << "Gracias por usar nuestro software" << endl;
break;
case 1:
cout << "indique valor a entrar:";
cin >> respuesta;

pila1.entrarDato(respuesta);
break;
case 2:
cout << "Dato obtenido:" << pila1.sacarDato() << endl;
break;
case 3:
cout << "Hay " << pila1.cuantosDatos() << " en la pila" << endl;
break;
case 4:
pila1.mostrarDatos();
}
}
return 0;

El programa completo ser obviamente la parte que define e implementa


la clase con la segunda que usa la funcin men y el main.
El switch es usado para atender cada una de las opciones que son
ofrecidas al usuario en el men.
Estudie el anterior programa hasta entenderlo completamente.

Ejercicio para Resolver No. 2

Hacer una versin de prog3 en el cual se use un apuntador a un vector


de enteros, es decir que la declaracin de vector no sea
int vector [50];

Sino que sea


int *vector;

Modifique el programa para que al entrar pida el tamao de la pila que el


usuario desea. Es decir, ya no ser de 50 posiciones fijas sino del
tamao que el usuario escoja al inicio del programa

Pila con apuntadores

El programa anterior se puede modificar para que maneje una lista


enlazada. En el caso actual usaremos una lista doblemente enlazada que
se comporta como una pila.
Tendremos una lista que usa dos apuntadores iniciales que son inicio y
final que manejarn la lista enlazada y permitirn tener una pila
implementada con apuntadores. Este programa desde el punto de vista
del usuario es completamente igual al anterior. Sin embargo, no tiene la
restriccin de las 50 posiciones.
prog3
#include "iostream.h"
struct nodo {
int campo;
struct nodo *anterior, *siguiente;
};

// Pila hecha con apuntadores


class Pila {
struct nodo *inicio, *final;
// indicePila:

-1 -> pila vacia

0 -> posicion del dato

int indicePila;
public:
Pila() {
indicePila = -1;
inicio = NULL;
final = NULL;
}; // constructor
// funciones analizadoras
void mostrarDatos();
int cuantosDatos();
// funciones modificadoras
void entrarDato(int dato);
int sacarDato();
~Pila();
};
// Esta funcin sale del cuerpo de la clase porque usa un ciclo.
void Pila::mostrarDatos() {

cout << endl << "DATOS EN LA PILA" << endl;


struct nodo *aux = inicio;
int i = 0;
while (aux != NULL) {
cout << "Dato No. " << i << " : " << aux->campo << endl;
i ++;
aux = aux->siguiente;
}
cout << endl;

int Pila::cuantosDatos() {
return indicePila + 1;
}
void Pila::entrarDato(int dato) {
struct nodo *nuevo = new struct nodo;
nuevo->campo = dato;
nuevo->siguiente = NULL;
nuevo->anterior = NULL;
if (final != NULL) {
final->siguiente = nuevo;
nuevo ->anterior = final;
} else
inicio = nuevo;
final = nuevo;
indicePila ++;

int Pila::sacarDato() {
struct nodo *aux = final;
cout << "valor ";
int valor;
if (aux != NULL) {
valor = aux->campo;
if (final != NULL)
final = final->anterior;
if (final != NULL)
final->siguiente = NULL;
else
inicio = NULL;
delete aux;

indicePila --;
return valor;
}
return -1;

Pila::~Pila() {
struct nodo *aux = inicio;
while (aux != NULL) {
inicio = inicio->siguiente;
delete aux;
aux = inicio;
}
}
int menu() {
cout << endl << endl;
cout << "Bienvenido al programa manejador de Pila de enteros" << endl;
cout << "Escoja una opcin" << endl;
cout << "**************************************" << endl;
cout << "0. Salir del Programa" << endl;
cout << "1. Adicionar entero" << endl;
cout << "2. Sacar entero" << endl;
cout << "3. Ver cuantos datos tiene la pila" << endl;
cout << "4. Mostrar datos en la pila" << endl;
cout << "**************************************" << endl;
int opcion;
cin >> opcion;
return opcion;

main () {
Pila pila1;
int respuesta,opcion;
opcion = -1;
while (opcion != 0) {
opcion = menu();
switch (opcion) {
case 0:
cout << "Gracias por usar nuestro software" << endl;
break;
case 1:

cout << "indique valor a entrar:";


cin >> respuesta;
pila1.entrarDato(respuesta);
break;
case 2:
cout << "Dato obtenido:" << pila1.sacarDato() << endl;
break;
case 3:
cout << "Hay " << pila1.cuantosDatos() << " en la pila" << endl;
break;
case 4:
pila1.mostrarDatos();
}
}
return 0;

Ejercicio para Resolver No. 3

Cree una clase que contenga una estructura (vector o apuntador) a la


cual se le puedan entrar 30 valores enteros. Estos enteros entrarn en
desorden pero siempre que se le solicite listar los valores estos debern
salir ordenados de menor a mayor.

You might also like