|
| |
Creación y Manipulación de Pilas con Punteros en Microsoft Visual C++ 2005
Resumen: Este programa permite crear pilas para posteriormente agregar o eliminar nodos a la pila creada. Los nodos que se crean siempre se ubican en la parte superior de la pila. Al eliminar un nodo, siempre se elimina el que está en la parte superior de la pila. Al nodo que se ubica encima de todos los otros nodos se le conoce como “nodo top”, pues se encuentra precisamente en la parte superior de la pila.
Publicación enviada por Jaime Oswaldo Montoya Guzmán
PRIMEROS PASOS
Primeramente, este programa ha sido creado en Microsoft Visual C++ 2005. Los
primeros pasos para crearlo son: Abrir Microsoft Visual Studio 2005; hacer
clic en el menú Archivo y luego en Nuevo Proyecto…; luego en Tipos de
Proyecto, en otros lenguajes, seleccionar Visual C++; después de eso en
Plantillas seleccionar Aplicación de Windows Forms; finalmente en ponerle el
nombre y la ubicación deseada al proyecto y hacer clic en Aceptar.
FUNCIONAMIENTO DEL PROGRAMA
Este programa permite crear pilas para posteriormente agregar o eliminar nodos
a la pila creada. Los nodos que se crean siempre se ubican en la parte
superior de la pila. Al eliminar un nodo, siempre se elimina el que está en la
parte superior de la pila. Al nodo que se ubica encima de todos los otros
nodos se le conoce como “nodo top”, pues se encuentra precisamente en la parte
superior de la pila. Esquemáticamente se tiene lo siguiente:

El nodo de color rojo representa el “top” o “nodo top”. Cuando un nuevo nodo
llega, justamente ese nuevo nodo se convertirá en el nuevo “top”. Si se quiere
eliminar un nodo, tendrá que ser el “nodo top”, pero antes deberá asignarle la
posición de “top” al nodo que le sigue (contando de arriba hacia abajo).
Agregar un nodo a la pila es un proceso conocido como “Push”. Eliminar un nodo
de la pila es un proceso conocido como “Pop”. Tal como se dijo anteriormente,
al hacer un “Push”, el nodo agregado se convierte en “top”, y al hacer un
“Pop”, el nodo que estaba después del “nodo top” se convierte en el nuevo
“nodo top” de la pila. La siguiente figura ilustra estos procesos:

Téngase presente que se está trabajando con estructuras, esto significa que un
nodo debe entenderse para este caso como una estructura de datos, es decir que
un nodo contiene tres campos: Nombre y Apellidos, Edad y Salario. Cada uno de
los nodos contendrá valores en esos tres campos, pues se está utilizando una
estructura personalizada que se creó antes de darle código a cada botón.
FORMULARIO Y OBJETOS EN TIEMPO DE DISEÑO

EJEMPLO DEL PROGRAMA EN EJECUCIÓN
Para comprender mejor el funcionamiento del programa, se hará un ejemplo y se
irán mostrando las pantallas de ejecución:
Creando Pila:

Se acaba de crear un nodo, que a la vez es el “nodo top”.
Agregando un nodo a la pila (haciendo clic en “Push”):

El nodo que era primero pasó a ser segundo, y ahora el nuevo “nodo top” es el
de “Melissa Ann Burchell”.
Agregando un tercer nodo a la pila (haciendo clic en “Push”):

El nodo recién agregado (el de Steven Hall) se convierte en el nuevo “nodo top”
y ahora hay 3 nodos en la pila.
Agregando un cuarto nodo a la pila (haciendo clic en “Push”):

El nodo recién agregado (el de Glenda Maritza Espana) se convierte en el nuevo
“nodo top” y ahora hay 4 nodos en la pila.
Agregando un quinto nodo a la pila (haciendo clic en “Push”):

El nodo recién agregado (el de Jennifer Esmeralda Chacon) se convierte en el
nuevo “nodo top” y ahora hay 5 nodos en la pila.
Eliminando un nodo de la pila (haciendo clic en “Pop”):

Ahora el nuevo “nodo top” es el de Glenda Maritza Espana, pues al hacer clic
en “Pop” se eliminó el que era antes el “nodo top” (el nodo de Jennifer
Esmeralda Chacon). Ahora hay solamente 4 nodos en la pila.
Eliminando un nodo de la pila (haciendo clic en “Pop”):

Ahora el nuevo “nodo top” es el de Steven Hall, pues al hacer clic en “Pop” se
eliminó el que era antes el “nodo top” (el nodo de Glenda Maritza Espana).
Ahora hay solamente 3 nodos en la pila.
Eliminando un nodo de la pila (haciendo clic en “Pop”):

Ahora el nuevo “nodo top” es el de Melissa Ann Burchel, pues al hacer clic en
“Pop” se eliminó el que era antes el “nodo top” (el nodo de Steven Hall).
Ahora hay solamente 2 nodos en la pila.
Eliminando un nodo de la pila (haciendo clic en “Pop”):

Ahora el nuevo “nodo top” es el de Jaime Montoya (y por cierto el único nodo
que tiene la pila en este momento), pues al hacer clic en “Pop” se eliminó el
que era antes el “nodo top” (el nodo de Melissa Ann Burchell). Como ya se
dijo, la pila tiene ahora solamente un nodo.
Eliminando un nodo de la pila (haciendo clic en “Pop”):

La pila no tiene ningún nodo en este momento. Al hacer clic en “Pop” se
eliminó el que era antes el “nodo top” (el nodo de Jaime Montoya).
En este momento ya no es posible eliminar nodos porque ya no hay ninguno, pero
se pueden agregar nuevamente nodos (con el botón “Push”) y luego volver a
eliminarlos (con el botón “Pop”) las veces que se desee.
CÓDIGO DEL PROGRAMA
Estando en tiempo de diseño, hacemos doble clic al formulario y luego nos
vamos a las primeras líneas de código que aparecen, e identificamos las
siguientes líneas de código que ya deben aparecer así predeterminadamente:
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
Justo abajo de las líneas anteriores, creamos nuestra estructura de datos:
//Se crea una estructura personalizada.
struct nodo{
char nombreyapellidos[100];//El nombre y apellidos podrán tener como máximo
100 caracteres.
int edad;
double salario;
nodo *abajo;//Utilizando recursividad, se declara un apuntador del tipo "nodopila",
que servirá para saber el nodo al que apunta otro determinado nodo.
};
nodo *current, *temporary, *top;//Se crean tres punteros/apuntadores. El
primero para apuntar a el "nodo actual", el segundo para el "nodo temporal" y
el último para el "nodo que está en el 'top' o parte superior de la pila".
Luego se crearán dos funciones para no tener que estar escribiendo el mismo
código varias veces. Esta funciones deben ubicarse justo arriba de la parte
del código en la que aparece predeterminadamente la siguiente línea:
#pragma endregion
Las funciones son las siguientes:
FUNCIÓN1: mostrarnodossuperioresdelapila()
//La función que se crea a continuación es para que cuando el usuario haga
clic en el botón "Crear Pila", "Push" o "Pop"; que el programa muestre/imprima
actualizadamente los "TRES NODOS SUPERIORES DE LA PILA".
int mostrarnodossuperioresdelapila(){
//Se borra lo que hay en los textBox que muestran los "TRES NODOS SUPERIORES
DE LA PILA" para que no queden impresos resultados de procesos anteriores.
textBox7->Text = "";
textBox8->Text = "";
textBox9->Text = "";
textBox10->Text = "";
textBox11->Text = "";
textBox12->Text = "";
textBox13->Text = "";
textBox14->Text = "";
textBox15->Text = "";
if (top != 0){//Si en la pila hay por lo menos un nodo, muestra el "nodo top"
de la pila en los textBox correspondientes.
for (int i=0; i<100; i++)//Hace 100 iteraciones, pues es el máximo que se ha
programado que puede tener de posiciones el arreglo tipo "char" donde se
almacena el nombre y los apellidos.
textBox7->Text += Char::ToString(top->nombreyapellidos[i]);//En cada iteración
va concatenando, de modo que toma las posiciones tipo "char" y las va poniendo
como una sola palabra/palabras de tipo "String" para ir a imprimir al textBox.
textBox8->Text = Convert::ToString(top->edad);//Imprime el valor almacenado en
el campo "Edad" del "nodo top".
textBox9->Text = Convert::ToString(top->salario);//Imprime el valor almacenado
en el campo "Salario" del "nodo top".
if (top->abajo != 0){//Si en la pila hay por lo menos dos nodos, muestra el
nodo 2 (contando desde arriba hacia abajo) o el nodo que está abajo del "nodo
top", en los textBox correspondientes.
for (int i=0; i<100; i++)//Hace 100 iteraciones, pues es el máximo que se ha
programado que puede tener de posiciones el arreglo tipo "char" donde se
almacena el nombre y los apellidos.
textBox10->Text += Char::ToString(top->abajo->nombreyapellidos[i]);//En cada
iteración va concatenando, de modo que toma las posiciones tipo "char" y las
va poniendo como una sola palabra/palabras de tipo "String" para ir a imprimir
al textBox.
textBox11->Text = Convert::ToString(top->abajo->edad);//Imprime el valor
almacenado en el campo "Edad" del nodo 2 (contando desde arriba o desde el "top"
hacia abajo).
textBox12->Text = Convert::ToString(top->abajo->salario);//Imprime el valor
almacenado en el campo "Salario del nodo 2 (contando desde arriba o desde el "top"
hacia abajo).
if (top->abajo->abajo != 0){//Si en la pila hay por lo menos tres nodos,
muestra el valor del nodo 3 (contando desde arriba hacia abajo) o el nodo que
está dos posiciones abajo del "nodo top", en los textBox correspondientes.
for (int i=0; i<100; i++)//Hace 100 iteraciones, pues es el máximo que se ha
programado que puede tener de posiciones el arreglo tipo "char" donde se
almacena el nombre y los apellidos.
textBox13->Text += Char::ToString(top->abajo->abajo->nombreyapellidos[i]);//En
cada iteración va concatenando, de modo que toma las posiciones tipo "char" y
las va poniendo como una sola palabra/palabras de tipo "String" para ir a
imprimir al textBox.
textBox14->Text = Convert::ToString(top->abajo->abajo->edad);//Imprime el
valor almacenado en el campo "Edad" del nodo 3 (contando desde arriba o desde
el "top" hacia abajo).
textBox15->Text = Convert::ToString(top->abajo->abajo->salario);//Imprime el
valor almacenado en el campo "Salario del nodo 3 (contando desde arriba o
desde el "top" hacia abajo).
}
}
}
return 0;//Necesario porque la función tiene que retornar un valor. Aunque en
vez de "0" pudo haber sido "-99.6", "-6", "0.3", "3", "140" o cualquier otro
número (siempre y cuando no se ponga uno exageradamente grande ni
exageradamente pequeño ni con exagerada cantidad de dígitos decimales).
}
FUNCIÓN 2: totaldenodosenlapila()
//La función que se crea a continuación es para que cuando el usuario haga
clic en el botón "Crear Pila", "Push" o "Pop"; que el programa muestre/imprima
el "Total de Nodos en la Pila".
int totaldenodosenlapila(){
int totaldenodos = 0;//La variable "totaldenodos" se inicializa con el valor
de 0.
if (top != 0){//Para que "totaldenodos" llegue a ser mayor que cero,
obviamente debe existir por lo menos un nodo. Entonces si todavía no ningún
nodo, por lo tanto no habría ningún "nodo top" y en consecuencia no se
entraría al "if" y "totaldenodos" continuaría valiendo cero.
current = top;//Debido a que se quiere contar el número total de nodos que
hay, se debe comenzar desde el "nodo top" hasta el último nodo de la pila
(hasta el que esté en el fondo de la pila o hasta abajo).
totaldenodos += 1;//Debido a que antes de llegar a esta línea se confirmó con
el "if (top != 0){" que ya existe un "nodo top", entonces "totaldenodos"
tendrá que valer 1 (es decir 0 que valía anteriormente más 1).
while (current->abajo != 0){//Mientras exista un nodo abajo del nodo actual,
seguirán las iteraciones (recuérdese que el nodo actual en la primera
iteración es el "nodo top".
totaldenodos += 1;//En cada iteración se le va sumando 1 a la variable "totaldenodos".
current = current->abajo;//En cada iteración el nodo actual ("current") pasa a
ser el nodo que está abajo del que era actual, es decir que va bajando una
posición. Por ejemplo, si hay 3 nodos en la pila, contando de arriba hacia
abajo, en la primera iteración el nodo actual ("current") será el nodo de
hasta arriba ("nodo top"), en la segunda iteración el nodo de en medio y en la
tercera iteración el nodo de hasta abajo (bottom).
}
}
textBox16->Text = Convert::ToString(totaldenodos);//Convierte el número entero
que contiene la variable "totaldenodos" al tipo String (para que sea posible
imprimirlo en un textBox) e imprime ese valor en el textBox16.
return 0;
}
Debajo de las dos funciones anteriores que se programaron, debe aparecer la
siguiente línea de código predeterminada por Visual C++ 2005:
#pragma endregion
Debajo de esa línea viene el código para cada uno de los botones. Sin embargo
no es necesario estar buscando esa línea para comenzar a darle código al
evento Clic de cada botón, pues basta darle doble clic a cada botón que se
quiere programar, estando en tiempo de diseño. El código completo para cada
uno de los botones es el siguiente:
CÓDIGO DEL BOTON PUSH

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {//Código para el evento Click del botón "Push" (que es el botón para que
se agregue un nodo y se ponga "encima" de todos los otros nodos de la pila, es
decir en el "top").
if (top != 0){//Para que si no existe ningún nodo (si no se ha creado todavía
ningún nodo), que el programa simplemente no haga nada.
//Se dertermina hacia dónde va a apuntar la variable apuntadora llamada "top".
current = new nodo;//Se crea un nuevo nodo utilizando la estructura creada
anteriormente.
//Con las próximas 6 líneas se llenan de información o datos los espacios de
memoria a los que se encuentra apuntando el apuntador "top".
for(int i=0;i<100;i++)//Para llenar cada posición del arreglo de espacios en
blanco y que así imprima espacios en blanco en vez de cualquier otra cosa en
los espacios que sobren en el caso que el nombre y apellidos tengan menos de
100 caracteres. Por ejemplo si el nombre y los apellidos ocupan 50 caracteres,
los otros 50 se llenarán de espacios en blanco y eso no afectará el programa
porque el usuario no percibirá ninguna diferencia visualmente.
current->nombreyapellidos[i]=' ';//En cada iteración se llena una posición de
un espacio en blanco, de modo que luego de las 100 iteraciones del ciclo "for",
las 100 posiciones estarán llenas de espacios en blanco.
//Con las próximas 2 líneas se llena cada posición del arreglo tipo "char" con
datos tomados del textBox1 y pasados de "String" a "char".
for(int i=0;i<textBox1->Text->Length;i++)//Si la longitud del texto
introducido en el textBox1 tiene 20 caracteres, el ciclo "for" hará 20
iteraciones, pues la condición que se ha puesto para que el ciclo continúe es
que la iteración actual (controlada por la variable "i") sea menor que la
longitud de caracteres que tiene el texto introducido por el usuario en el
textBox1.
current->nombreyapellidos[i] = textBox1->Text[i];
current->edad = Convert::ToInt64(textBox2->Text);//La edad "String" del
textBox2 se convierte a tipo entero ("int") y se manda a la variable
correspondiente dentro de la estructura creada.
current->salario = Convert::ToDouble(textBox3->Text);//El salario "String" del
textBox3 se convierte a tipo "double" y manda a la variable correspondiente
dentro de la estructura creada.
current->abajo = top;//Para que el apuntador del nodo recién creado (que se
iría a ubicar encima de toda la pila), apunte hacia el nodo que hasta este
momento era el "top" (pero que pasará a ser el segundo nodo de la pila
contando de arriba hacia abajo).
top = current;//El nodo recién creado se convierte en el nuevo "top" de la
pila o el que está hasta arriba (encima de todos los otros nodos).
mostrarnodossuperioresdelapila();//Se invoca la función que se creó
anteriormente y que sirve para mostrar/imprimir actualizadamente los "TRES
NODOS SUPERIORES DE LA FILA", aunque puede mostrar solamente 2, 1 e incluso 0
nodos, dependiendo de cuántos tenga la pila.
totaldenodosenlapila();//Se invoca la función que se creó anteriormente y que
sirve para mostrar/imprimir actualizadamente el "Total de Nodos en la Pila".
}
}
CÓDIGO DEL BOTON CREAR PILA

private: System::Void button3_Click(System::Object^ sender, System::EventArgs^
e) {//Código para el evento Click del botón "Crear Pila".
//Se dertermina hacia dónde va a apuntar la variable apuntadora llamada "top".
top = new nodo;//Se crea un nuevo nodo utilizando la estructura creada
anteriormente.
//Con las próximas 6 líneas se llenan de información o datos los espacios de
memoria a los que se encuentra apuntando el apuntador "top".
for(int i=0;i<100;i++)//Para llenar cada posición del arreglo de espacios en
blanco y que así imprima espacios en blanco en vez de cualquier otra cosa en
los espacios que sobren en el caso que el nombre y apellidos tengan menos de
100 caracteres. Por ejemplo si el nombre y los apellidos ocupan 50 caracteres,
los otros 50 se llenarán de espacios en blanco y eso no afectará el programa
porque el usuario no percibirá ninguna diferencia visualmente.
top->nombreyapellidos[i]=' ';//En cada iteración se llena una posición de un
espacio en blanco, de modo que luego de las 100 iteraciones del ciclo "for",
las 100 posiciones estarán llenas de espacios en blanco.
//Con las próximas 2 líneas se llena cada posición del arreglo tipo "char" con
datos tomados del textBox1 y pasados de "String" a "char".
for(int i=0;i<textBox1->Text->Length;i++)//Si la longitud del texto
introducido en el textBox1 tiene 20 caracteres, el ciclo "for" hará 20
iteraciones, pues la condición que se ha puesto para que el ciclo continúe es
que la iteración actual (controlada por la variable "i") sea menor que la
longitud de caracteres que tiene el texto introducido por el usuario en el
textBox1.
top->nombreyapellidos[i] = textBox1->Text[i];
top->edad = Convert::ToInt64(textBox2->Text);//La edad "String" del textBox2
se convierte a tipo entero ("int") y se manda a la variable correspondiente
dentro de la estructura creada.
top->salario = Convert::ToDouble(textBox3->Text);//El salario "String" del
textBox3 se convierte a tipo "double" y manda a la variable correspondiente
dentro de la estructura creada.
top->abajo = 0;//Por ser nodo que está hasta abajo en la pila, apunta hacia
cero y como es el único existente, es el "top" y a la vez el "bottom".
mostrarnodossuperioresdelapila();//Se invoca la función que se creó
anteriormente y que sirve para mostrar/imprimir actualizadamente los "TRES
NODOS SUPERIORES DE LA FILA", aunque puede mostrar solamente 2, 1 e incluso 0
nodos, dependiendo de cuántos tenga la pila.
totaldenodosenlapila();//Se invoca la función que se creó anteriormente y que
sirve para mostrar/imprimir actualizadamente el "Total de Nodos en la Pila".
}
CÓDIGO DEL BOTON POP

private: System::Void button2_Click(System::Object^ sender, System::EventArgs^
e) {//Código para el evento Click del botón "Pop" (que es el botón para que se
elimine el nodo que está "encima" de todos los otros nodos de la pila, es
decir el del "top").
textBox4->Text = textBox7->Text;//El nombre y apellidos del "nodo top"
aparecen en el textBox4, pero al hacer clic en el botón "Pop" (eliminar nodo "top"),
es el "nodo top" el que se elimina (tal como se ha programado dentro de la la
condición "if" que viene a continuación), de modo que en el textBox7 aparece
el nombre y apellidos del nodo eliminado.
textBox5->Text = textBox8->Text;//La edad del "nodo top" aparece en el
textBox5, pero al hacer clic en el botón "Pop" (eliminar nodo "top"), es el
"nodo top" el que se elimina (tal como se ha programado dentro de la condición
"if" que viene a continuación), de modo que en el textBox8 aparece la edad del
nodo eliminado.
textBox6->Text = textBox9->Text;//El salario del "nodo top" aparece en el
textBox6, pero al hacer clic en el botón "Pop" (eliminar nodo "top"), es el
"nodo top" el que se elimina (tal como se ha programado dentro de la condición
"if" que viene a continuación), de modo que en el textBox9 aparece el salario
del nodo eliminado.
if (top != 0){//Porque cuando el "top" sea cero significa que no hay ningún
nodo en la fila, y esta condición se pone porque si no se pusiera, la línea "top
= top->abajo;" daría error porque se estaría haciendo referencia a algo que no
existe, pues si el "top" es cero ya no existe nada abajo del cero (ningún
nodo).
temporary = top;//Debido a que el nodo "top" es el que se va a eliminar, se
almacena en la variable "temporary" para luego asignarle el "top" al nodo que
quedará como nuevo "top" de la pila y hasta entonces eliminar con toda
libertad el nodo que hasta este momento es todavía "top".
top = top->abajo;//Debido a que se eliminará el nodo "top", con esto se asigna
quién será el nuevo nodo "top".
delete(temporary);//Se elimina el primer nodo de la pila (contando desde
arriba hacia abajo), el que anteriormente era el nodo "top" pero que ya no lo
es más y que será eliminado.
mostrarnodossuperioresdelapila();//Se invoca la función que se creó
anteriormente y que sirve para mostrar/imprimir actualizadamente los "TRES
NODOS SUPERIORES DE LA PILA", aunque puede mostrar solamente 2, 1 e incluso 0
nodos, dependiendo de cuántos tenga la pila.
totaldenodosenlapila();//Se invoca la función que se creó anteriormente y que
sirve para mostrar/imprimir actualizadamente el "Total de Nodos en la Pila".
}
}
CÓDIGO DEL BOTON LIMPIAR

rivate: System::Void button4_Click(System::Object^ sender, System::EventArgs^
e) {//Código para el evento Click del botón "Limpiar".
//Se limpian los textBox de los campos desde los que se agregar registros a un
nodo.
textBox1->Text = "";
textBox2->Text = "";
textBox3->Text = "";
}
AUTOR
Jaime Oswaldo Montoya Guzmán, estudiante de Ingeniería en Sistemas
Informáticos de la Universidad Católica de Occidente.
jaimemontoya@gmail.com
http://www.geocities.com/jaimemontoya1
Santa Ana, 2 de junio de 2007.
Universidad Católica de Occidente (UNICO).
El Salvador.
Compartir 
Publicación enviada por Jaime Oswaldo Montoya Guzmán
Contactar jaimemontoya@gmail.com
Código ISPN de la Publicación EElEEZuyEAYyaRNOOi
Publicado Wednesday 6 de June de 2007
Ultimas Publicaciones en ilustrados.com
ilustrados.com nace con el fin difundir el conocimiento publicando trabajos de investigación, monografias, tesis, presentaciones powerpoint y afines. Publicar trabajos en ilustrados.com ha alcanzado prestigio y reconocimiento internacional siendo cada vez más el número de académicos, empresas, investigadores, científicos que consultan las publicaciones de nuestro portal.
|