Ilustrados comunidad mundial educativa
Inicio | Escribenos
User: Pass: Recordar ó (Registrate!)

| !Publicar Articulo¡

Creación y manipulación de filas con punteros por el Método Circular doblemente ligado en Microsoft Visual C++ 2005

Resumen: Este programa permite crear filas para posteriormente agregar o eliminar nodos a la fila creada. Los nodos pueden ser agregados al final de la fila o en una posición cualquiera (llamada posición “k”) determinada por el usuario. Igualmente el programa permite eliminar el primer nodo de la fila así como también eliminar un nodo cualquiera ubicado en la posición “k”, que será también determinada por el usuario.
2,382 visitas
Rating: 0
Tell a Friend
Autor: Jaime Montoya

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 filas para posteriormente agregar o eliminar nodos a la fila creada. Los nodos pueden ser agregados al final de la fila o en una posición cualquiera (llamada posición “k”) determinada por el usuario. Igualmente el programa permite eliminar el primer nodo de la fila así como también eliminar un nodo cualquiera ubicado en la posición “k”, que será también determinada por el usuario. 

Mediante los botones de navegación el usuario podrá desplazarse al primero de todos los nodos, a un nodo anterior, a un nodo siguiente o al último de todos los nodos.

Es importante notar que se está trabajando con el método o modelo Circular Doblemente Ligado. Esto significa que el primer nodo de la fila tiene como nodo anterior el último nodo de la fila y el último nodo de la fila tiene como nodo siguiente el primer nodo de la fila. El primer nodo de la fila es conocido como “header”. En este modelo cada nodo apunta hacia uno nodo siguiente así como también hacia un nodo anterior. Por ejemplo: Supongamos que tenemos una fila que tiene 4 nodos, los punteros funcionarán entonces de la siguiente manera:

El nodo 1 (que es el “header”, primer nodo de todos o primer nodo de la fila) apunta hacia el nodo 2 como su nodo siguiente y hacia el nodo 4 (que es el último nodo de todos o el último nodo de la fila) como su nodo anterior. El nodo 2 apunta hacia el nodo 3 como su nodo siguiente y hacia el nodo 1 como su nodo anterior. El nodo 3 apunta hacia el nodo 4 como su nodo siguiente y hacia el nodo 2 como su nodo anterior. Finalmente el nodo 4 apunta hacia el nodo 1 como su nodo siguiente y hacia el nodo 3 como su nodo anterior. Si el usuario decide que la posición “k” es la posición 3, y luego hace clic en el botón “Agregar Nodo en la Posición k”, entonces el nodo 3 será el nuevo recién creado/agregado y el nodo que era el 3 pasará a ser el 4, de modo que se correrá un espacio hacia adelante. Por supuesto que los apuntadores deberán tenerse en cuenta también, de modo que el nodo recién agregado en la posición 3 deberá apuntar hacia el nodo que ahora ocupa la posición 4 como su nodo siguiente y hacia el nodo que está en la posición 2 como su nodo anterior. Igualmente el nodo 2 tendrá que dejar de apuntar hacia el nodo siguiente al que estaba apuntando y ahora apuntará al nuevo nodo recién introducido en la posición 3 como su nodo siguiente. En el caso que el usuario decida agregar un nodo en la posición 1, significa que el “header” será desplazado a la posición 2 y el nuevo “header” será el nodo recién creado/agregado. Lo importante es siempre tener cuidado de enlazar los apuntadores correctamente cada vez que se agrega o elimina un nodo, teniendo especial cuidado de siempre tener en cuenta qué nodo es nuestro “header” o primer nodo de la fila. Cuando se elimine el “header”, el nodo de la posición 2 de la fila pasará a ser el nuevo “header”, de modo que primer se desconecta el “header”, luego se hacen las conexiones de los apuntadores correspondientes y entonces se puede eliminar el primer nodo de la fila, luego de haber asignado al nodo 2 como nuestro nuevo “header”.

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 Fila:

Agregando un nodo al final de la fila:

 Agregando un nodo en medio de los dos nodos anteriormente creados (en la posición 2, pues “k” vale 2). Esto significa que el nodo 2 pasará a ser el nodo 3 y que se harán las conexiones respectivas de los apuntadores:

 

Eliminando el nodo de la posición 1 (es decir eliminando el “header”). Esto significa que el nuevo “header” pasará a ser el nodo 2:

Para comprobar que las todo está trabajando bien, se procede a navegar entre los nodos. Primeramente hacemos clic en el botón “Ir al Primer Nodo de Todos”: 
 

Debido a que se eliminó el “header” anteriormente, nótese que el que era “un nodo intermedio” (pues estaba en la posición 2, entre el nodo 1 (“header”) y el nodo 3 (último nodo de todos), ha pasado a ser nuestro “header”, pues es el primer nodo de todos. 

Ahora hacemos clic en el botón “Ir al Último Nodo de Todos:

Luego hacemos clic en el botón Siguiente:

 

Estábamos en el nodo 2 (último nodo de todos), y al hacer clic en el botón Siguiente, llegamos al nodo 1 (primer nodo de todos o “header”). Este es el efecto de trabajar con el Método Circular Doblemente Ligado.

Ahora hacemos clic en el botón Anterior: 
 

Estábamos en el nodo 1 (primer nodo de todos o “header”), y al hacer clic en el botón Anterior hemos llegado al nodo 2 (que es el último nodo de todos). Este es el efecto de trabajar con el Método Circular Doblemente Ligado.

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 y a la vez declaramos una variable pública: 
//Se crea una estructura personalizada.
      struct nodo
    {
            int edad;
            double salario;
            char nombreyapellidos[100];
            nodo *siguiente, *anterior;//También se puede poner "struct nodo *siguiente, *anterior;", pero no es necesario poner la palabra "struct" al principio.

     };

    nodo *current, *temporary, *header;//Se inicializan 3 punteros del tipo "nodo", pues ya "nodo" es un tipo de datos (por la estructura recién creada), como decir "int", "char", "float", etc. También se puede poner "struct nodo *p, *q, *header;", pero no es necesario poner la palabra "struct" al principio. 

      int totaldenodos;//Para contar el número total de nodos que hay. Esta variable llamada "contador" es pública, pues no funcionará solamente dentro de un objeto o evento de un botón en específico, sino que en todo el programa.

Posteriormente se hace doble clic sobre cada botón al que se le quiere asignar código para el evento Click. Aparecerán comentarios en color verde a lo largo de todo el código para explicar el funcionamiento y la lógica que se ha seguido en la creación de este programa. El código completo para todos los botones es el siguiente:
 

Código del Botón Crear Fila 

 
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Crear Fila".

totaldenodos=0;//Cuando se le da clic al botón "Crear", la cuenta del número total de nodos se reinicia (es decir vuelve a comenzar con cero nodo como número total de nodos en la fila, aunque aumentará a uno precisamente con el nodo que se creará con el evento Click de este botón, según lo programado con la línea "totaldenodos+=1;").

//Se dertermina hacia dónde va a apuntar la variable apuntadora llamada "header".

header = new nodo;//Se le puede poner "header = new struct nodo;", pero no es necesario poner la palabra "struct".

//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.

header->edad = Convert::ToInt64(textBox1->Text);
header->salario = Convert::ToDouble(textBox2->Text);

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 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.

      header->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 textBox3 y pasados de "String" a "char".

for(int i=0;i<textBox3->Text->Length;i++)

      header->nombreyapellidos[i] = textBox3->Text[i];

//Con las próximas 2 líneas se define que el apuntador del nodo recién creado apunte a él mismo ya sea si se quiere navegar hacia adelante o hacia atrás, debido a que el modelo con el que se está trabajando es "Circular Doblemente Ligado".

header->anterior = header;
header->siguiente = header;

current = header;//Para que cuando se haga clic en el botón Anterior o Siguiente, se sepa que el nodo recién creado es el "header" (primer nodo de la fila).
totaldenodos+=1;//Le suma 1 al número total de nodos que hay en la fila.
textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.                     

}

 Código del Botón Agregar Nodo al Final 

 private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Agregar Nodo al Final".

if (header != 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 determina hacia dónde va a apuntar la variable apuntadora llamada "current".

current = new nodo;//Se le puede poner "header = new struct nodo;", pero no es necesario poner la palabra "struct".

//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.

current->edad = Convert::ToInt64(textBox1->Text);
current->salario = Convert::ToDouble(textBox2->Text);

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 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 textBox3 y pasados de "String" a "char".

for(int i=0;i<textBox3->Text->Length;i++)

current->nombreyapellidos[i] = textBox3->Text[i];

//Para que el apuntador del nodo recién creado (que se iría a posicionar como último nodo de la fila) apunte al primer nodo de la fila (el "header"), pues se está trabajando con el modelo "Circular Doblemente Ligado".

current->siguiente = header;

//Las 4 líneas anteriores han sido para crear un nuevo nodo. Las 4 líneas siguientes serán para posicionar el nodo recién creado en la última posición de la fila, de modo que sea el último nodo de todos.

temporary = header;//Un apuntador llamado "temporary" apunta al apuntador "header", para comenzar a hacer los procesos que se deseen desde el primer nodo de la fila, que es lo que apunta el "header".

while (temporary->siguiente != header)//Cuando "temporary->siguiente" sea igual a "header", significa que ya nos encontramos en el último nodo de la fila, pues el último nodo de la fila es el que apunta al header (por estar trabajando con el modelo "Circular Doblemente Ligado"). Mientras eso no haya sucedido, se debe seguir avanzando hasta llegar al último nodo, que es el que se quiere encontrar debido a que después de ese nodo es que se va a agregar el nuevo nodo y así quedará como el último nodo de todos o el último de la fila.

temporary = temporary->siguiente;//Con esto se avanza hacia el siguiente nodo siempre que la condición del while todavía se cumpla.

temporary->siguiente = current;//Estando fuera del while, debido a que ya se detectó cuál es el último nodo, ahora se agrega un nuevo nodo ubicado en la última posición, es decir como último nodo de toda la fila.

current->anterior = temporary;//Luego de haber agregado un nuevo nodo, se especifíca cuál es el penúltimo nodo, lo cual será importante saber para cuando se programe la navegación hacia atrás, es decir irse desplazando de uno en uno hacia nodos anteriores hasta llegar al primero de todos.

header->anterior = current;//Para que cuando esté en el primer nodo de todos, que el nodo anterior sea el último nodo de todos, que dos líneas arriba se acaba de programar cuál será el último nodo de todos ("temporary->siguiente = current;"). Esto tomando en cuenta que se está trabajando con el modelo "Circular Doblemente Ligado", de modo que si está en el último nodo de todos y quiere irse al siguiente, se iría al primer nodo de todos; y si está en el primer nodo de todos y quiere irse al anterior, se iría al último nodo de todos.

totaldenodos+=1;//Le suma 1 al número total de nodos que hay en la fila.

textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.               

}

} 

Código del Botón Anterior 

 private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Anterior".

if (header != 0){//Para que si no existe ningún nodo (si no se ha reado todavía ningún nodo), que el programa simplemente no haga nada.     

current = current->anterior;//El nodo anterior al actual pasa a ser el nuevo nodo actual.

//Las siguientes cinco líneas muestran en pantalla el nodo anterior, que gracias a lo que se hizo en la línea anterior se convierte en nuestro nuevo nodo actual.

textBox1->Text = Convert::ToString(current->edad);
textBox2->Text = Convert::ToString(current->salario);
textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

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.

textBox3->Text += Char::ToString(current->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.

}

} 

Código del Botón Siguiente 

 private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Siguiente".

if (header != 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.

current = current->siguiente;//El nodo siguiente al actual pasa a ser el nuevo nodo actual.

//Las siguientes cinco líneas muestran el nodo siguiente, que gracias a lo que se hizo en la línea anterior se convierte en nuestro nuevo nodo actual.

textBox1->Text = Convert::ToString(current->edad);
  
         textBox2->Text = Convert::ToString(current->salario);
            textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

      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.

            textBox3->Text += Char::ToString(current->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.

}

} 

Código del Botón Eliminar Primer Nodo 

 private: System::Void button5_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Eliminar Primer Nodo".

if (header != 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.

if (header->siguiente != header){//Para que elimine únicamente cuando el "header" tenga un nodo siguiente que no sea precisamente el "header" mismo (pues se está trabajando con el modelo "Circular Doblemente Ligado"). En caso contrario (si el siguiente del "header" fuera él mismo) significa que la fila tiene un solo nodo y por lo tanto no se tendría que eliminar, por lo cual no se entraría al "if".

            temporary = header;//Debido a que se quiere eliminar el primer nodo de la fila (que sería el "header"), en una variable llamada "temporary" se almacena el "header".

            header = header->siguiente;//El nuevo "header" será el segundo nodo de la fila, pues el primer nodo de la fila se eliminará.

            header->anterior = 0;//Se desconecta el segundo nodo de la fila (que pasará a ser nuestro nuevo primer nodo de la fila o "header") del primer nodo de la fila (que es el que se va a eliminar).

            header->anterior = temporary->anterior;//Se conecta el segundo nodo de la fila (que pasará a ser nuestro primer nodo de la fila o "header") con el último nodo de la fila, pues se está trabajando con el modelo "Circular Doblemente Ligado".

            temporary->siguiente = 0;//Se desconecta el primer nodo de la fila (que será eliminado) del segundo nodo de la fila (que pasará a ser el primer nodo de la fila).

            temporary->anterior = 0;//Se desconecta el primer nodo de la fila (que será eliminado) del último nodo de la fila (pues por estar trabajando con el modelo "Circular Doblemente Ligado", el primer nodo de la fila siempre va conectado al último nodo de la fila).                 

            delete(temporary);//Se elimina el primer nodo de la fila, pero nótese que antes de eliminarlo primero se desconectó y se hicieron las conexiones correspondientes mediante las líneas anteriores de código para el botón Eliminar.               

            current = header;//Para que cuando se haga clic en el botón Anterior o Siguiente no tome como nodo actual el nodo que se acaba de eliminar, sino que tome como nodo actual el nuevo "header".

            header->anterior->siguiente = header;//Esto se hace para que el último nodo no quede apuntando al nodo recién eliminado, sino que el último nodo de todos quede apuntando al nuevo header.

            textBox1->Text = Convert::ToString(current->edad);//Imprime la edad del nuevo nodo "header" (primer nodo de la fila), pues lo que se eliminó es el que era antes el "header".

            textBox2->Text = Convert::ToString(current->salario);//Imprime el salario del nuevo "header" (primer nodo de la fila), pues lo que se eliminó es el que era antes el "header".

            textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

            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.

                  textBox3->Text += Char::ToString(current->nombreyapellidos[i]);//Imprime el nombre y apellidos del nuevo nodo "header" (primer nodo de la fila), pues lo que se eliminó es el que era antes el "header". 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.

            totaldenodos-=1;//Le resta 1 al número total de nodos que hay en la fila.

            textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.

            }

}

}

 Código del Botón Agregar Nodo en la Posición k 

 private: System::Void button6_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Agregar Nodo en la Posición k".

if (header != 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.

if (Convert::ToDouble(textBox4->Text) <= Convert::ToDouble(textBox6->Text)){//Si la posición "k" es igual o menor que el número total de nodos existente en la fila, se comienzan a hacer los procesos correspondientes. De lo contrario el programa no hace nada.

//Se determina hacia dónde va a apuntar la variable apuntadora llamada "current".

current = new nodo;//Se le puede poner "header = new struct nodo;", pero no es necesario poner la palabra "struct".

            //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.

            current->edad = Convert::ToInt64(textBox1->Text);
            current->salario = Convert::ToDouble(textBox2->Text);

            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 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 textBox3 y pasados de "String" a "char".

                  for(int i=0;i<textBox3->Text->Length;i++)

                        current->nombreyapellidos[i] = textBox3->Text[i];   

temporary = header;//Con esto se podrá comenzar a contar desde el primer nodo de la fila, que es el "header".

                  if (Convert::ToInt64(textBox4->Text)==1){//En caso que "k" valga 1, es decir que se quiera agregar un nodo en la primera posición y que pase a ser el nuevo "header" (primer nodo de todos en la fila) de la fila.

                        current->siguiente = header;//"current" es el nodo que se está agregando/creando como nuevo "header". Debido a que el que es "header" dejará de serlo y pasará a ser el segundo nodo de la fila, entonces el nuevo nodo ("current") tendrá como su nodo siguiente al que hasta este momento es todavía "header".

                        current->anterior = header->anterior;//"current" es el nodo que se está agregando/creando como nuevo "header". El nuevo "header" tendrá como nodo anterior al mismo nodo que el nodo que dejará de ser "header" tiene como anterior.

                        header->anterior = current;//El "header" pasará a ser segundo de la fila porque el nodo "current" se convertirá en nuestro nuevo "header". Entonces el que todavía es "header" (y que pasará a ser segundo nodo de la fila) tendrá como nodo anterior a "current" (que será nuestro nuevo "header").

                        current->anterior->siguiente = current;//"current->anterior->siguiente" hace referencia al nodo siguiente del último nodo de la fila. En pocas palabras significa que el último nodo de la fila ("current->anterior" es el último nodo de la fila, pues por estar trabajando con el model "Circular Doblemente Ligado", "current" será nuestro nuevo "header" y tendrá como anterior al último nodo de toda la fila) tendrá como nodo siguiente al primer nodo de toda la fila, que es "current", que pasará a ser el nuevo "header".

                        header = current;//Con esto se especifica que nuestro nuevo "header" (primer nodo de toda la fila) es "current".
                        totaldenodos+1;//Le suma 1 al número total de nodos que hay en la fila.
                        textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.

                        }else{//En caso qe "k" no valga 1, es decir que se quiera agregar un nodo en una posición en la que el nuevo nodo no pasará a ser el "header" (primer nodo de la fila) de la fila.

                              for (int i=1; i<Convert::ToInt64(textBox4->Text); i++)//Si "k" vale 4, se harían 3 iteraciones; si "k" vale 5 se hacen 4 iteraciones; y así sucesivamente. Si el usuario elije "k = 3", entonces si se agregara un nuevo nodo en la posición "k", se crearía y se iría a ubicar en la posición 3, de manera que el que era 3 pasaría a ser el 4, el que era 4 pasaría a ser 5 y así sucesivamente.

                                   temporary = temporary->siguiente;//En la última iteración del ciclo "for", en "temporary" se capturaría el nodo "k", que es donde se desea ir a ubicar el nuevo nodo recién creado, y correr este nodo "temporary" una posición adelante, cuidando siempre de conectar correctamente cada nodo con su respectivo nodo anterior y siguiente.

                             current->siguiente = temporary;//Estando fuera del ciclo "for", el nodo siguiente del nodo recién creado sería "temporary". Por ejemplo, si el usuario decidió crear/agregar el nuevo nodo en la posición 3, entonces "temporary" almacenaría el nodo que antes estaba en la posición 3 pero que ahora tendrá que pasar a la posición 4, y con esto se conecta el nodo 3 (recién creado/agregado) con el nodo 4 (que se tuvo que adelantar una posición, pues estaba en la posición 3 y pasaría a la posición 4).

                             current->anterior = temporary->anterior;//El anterior del nodo recién creado/agregado sería el que era anterior del "temporary". Por ejemplo, si el usuario decidió crear/agregar el nuevo nodo en la posición 3, entonces "temporary" tenía como anterior el nodo 2, pero ahora el nodo 2 pasará a ser el anterior del nuevo nodo recién creado en la posición 3.

                             temporary->anterior = current;//El nodo que fue desplazado un espacio hacia adelante apunta hacia el nuevo nodo recién creado. Por ejemplo si el nodo recién creado/agregado se fue a ubicar a la posición 3, el nodo que estaba en la posición 3 pasa a la posición 4 y apunta como su nodo anterior hacia la posición 3 (que sería "current" el nodo 3 en este caso o en este ejemplo).

                             current->anterior->siguiente = current;//El nodo que está atrás del nodo recién creado debe apuntar hacia el nodo recién creado como su nodo siguiente y no hacia el nodo al que estaba apuntando antes de la aparición de este nuevo nodo que acaba de llegar. Por ejemplo, el nodo 2 estaba apuntando al nodo 3, pero cuando llega el nuevo nodo en la posición 3, el nodo que era el 3 pasa a ser el nodo 4 y el nodo 2 debe apuntar hacia el nuevo nodo que se vino a ubicar en la posición 3 y no hacia el que actualmente sería el nodo 4.                                        

                        totaldenodos+=1;//Le suma 1 al número total de nodos que hay en la fila.
                        textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.                      

                              }

                         }                     

                   }

             }

 Código del Botón Eliminar Nodo en la Posición k 

 private: System::Void button7_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Eliminar Nodo en la Posición k".

if (header != 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.

if (Convert::ToDouble(textBox4->Text) <= Convert::ToDouble(textBox6->Text)){//Si la posición "k" es igual o menor que el número total de nodos existente en la fila, se comienzan a hacer los procesos correspondientes. De lo contrario el programa no hace nada.

            if (header->siguiente != header){//Para que elimine únicamente cuando el "header" (primer nodo de la fila) tenga un nodo siguiente que no sea precisamente el "header" mismo (pues se está trabajando con el modelo "Circular Doblemente Ligado"). En caso contrario (si el siguiente del "header" fuera él mismo) significa que la fila tiene un solo nodo y por lo tanto no se tendría que eliminar, por lo cual no se entraría al "if".

                  temporary = header;//Con esto se podrá comenzar a contar desde el primer nodo de la fila, que es el "header".

                  for (int i=1; i<Convert::ToInt64(textBox4->Text); i++)//Si "k" vale 3, se harían 2 iteraciones; si "k" vale 4 se harían 3 iteraciones; y así sucesivamente. En caso que "k" valiera 3 significa que lo que se desea hacer es eliminar el nodo 3, de modo que el ciclo "for" servirá para identificar el nodo que se desea eliminar.

                        temporary = temporary->siguiente;//En la última iteración del ciclo "for", en "temporary" se capturaría el nodo "k" que es el que se desea eliminar.

                  if (temporary == header){//En caso que lo que se quiera eliminar sea el primer nodo de la fila (es decir el "header").

                        if (header->siguiente != header){//Para que elimine únicamente cuando el "header" (primer nodo de la fila) tenga un nodo siguiente que no sea precisamente el "header" mismo (pues se está trabajando con el modelo "Circular Doblemente Ligado". En caso contrario (si el siguiente del "header" fuera él mismo) significa que la fila tiene un solo nodo y po rlo tanto no se tendráa que eliminar, por lo cual no se entraría al "if".

                              header = header->siguiente;//El nuevo "header" será el segundo nodo de la fila, pues el primer nodo de la fila se eliminará.

                        header->anterior = 0;//Se desconecta el segundo nodo de la fila (que pasará a ser nuestro nuevo primer nodo de la fila o "header") del primer nodo de la fila (que es el que se va a eliminar).

                        header->anterior = temporary->anterior;//Se conecta el segundo nodo de la fila (que pasará a ser nuestro primer nodo de la fila o "header") con el último nodo de la fila, pues se está trabajando con el modelo "Circular Doblemente Ligado".

                        temporary->siguiente = 0;//Se desconecta el primer nodo de la fila (que será eliminado) del segundo nodo de la fila (que pasará a ser el primer nodo de la fila).
                        temporary->anterior = 0;//Se desconecta el primer nodo de la fila (que será eliminado) del último nodo de la fila (pues por estar trabajando con el modelo "Circular Doblemente Ligado", el primer nodo de la fila siempre va conectado al último nodo de la fila).

                        delete(temporary);//Se elimina el primer nodo de la fila, pero nótese que antes de eliminarlo primero se desconectó y se hicieron las conexiones correspondientes, así como también se determinó quién será el nuevo "header".

                        current= header;//Para que cuando se haga clic en el botón Anterior o Siguiente no tome como nodo actual el nodo que se acaba de eliminar, sino que tome como nodo actual el "header" actual.

                        header->anterior->siguiente = header;//Esto se hace para que el último nodo no quede apuntando al nodo recién eliminado, sino que el último nodo de todos quede apuntando al nuevo header.

                        textBox1->Text = Convert::ToString(current->edad);//Imprime la edad del nodo actual (el "header" o primer nodo de la fila).                                                    textBox2->Text = Convert::ToString(current->salario);//Imprime el salario del nodo actual (el "header" o primer nodo de la fila)               

                        textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

                        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.

                              textBox3->Text += Char::ToString(current->nombreyapellidos[i]);//Imprime el nombre y apellidos del nodo actual (el "header" o primer nodo de la fila). 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.

                        totaldenodos-=1;//Le resta 1 al número total de nodos que hay en la fila.
                        textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.                 }                                 

            }else{//En caso que no sea el "header" el que se quiere eliminar, es decir que "temporary" sea diferente de "header" o "temporary != header".

                  temporary->anterior->siguiente = temporary->siguiente;//"temporary" es el nodo que se quiere eliminar, es decir el nodo "k". Supongamos que "temporary" es el nodo 3, con esta línea se logra que el nodo siguiente del nodo 2 pase a ser el nodo 4 (pues el nodo 3 se va a eliminar y el nodo 4 pasará a ser el nodo 3).

                  temporary->siguiente->anterior = temporary->anterior;//"temporary" es el nodo que se quiere eliminar, es decir el nodo "k". Supongamos que "temporary" es el nodo 3, con esta línea se logra que el nodo anterior del nodo 4 pase a ser el nodo 2 (pues el nodo 3 se va a eliminar y el nodo 4 pasará a ser el nodo 3).

                  temporary->siguiente = 0;//Se desconecta el nodo que se va a eliminar del nodo siguiente al que apuntaba.
                  temporary->anterior = 0;//Se desconecta el nodo que se va a eliminar del nodo anterior al que apuntaba.
                  delete(temporary);//Se elimina el nodo correspondiente a la posición "k" determinada por el usuario.

                  current = header;//Para que cuando se haga clic en el botón Anterior o Siguiente no tome como nodo actual el nodo que se acaba de eliminar, sino que tome como nodo actual el "header" actual.

                  textBox1->Text = Convert::ToString(current->edad);//Imprime la edad del nodo actual (el "header" o primer nodo de la fila).
                  textBox2->Text = Convert::ToString(current->salario);//Imprime el salario del nodo actual (el "header" o primer nodo de la fila).
                  textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

                  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.

                        textBox3->Text += Char::ToString(current->nombreyapellidos[i]);//Imprime el nombre y apellidos del nodo actual (el "header" o primer nodo de la fila). 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.

                  totaldenodos-=1;//Le resta 1 al número total de nodos que hay en la fila.
                  textBox6->Text = Convert::ToString(totaldenodos);//Imprime en el textBox6 el número total de nodos que hay en la fila.

                        }                

                  }

            }

}

}

private: System::Void groupBox3_Enter(System::Object^  sender, System::EventArgs^  e) {

             } 

Código del Botón Ir al Primer Nodo de Todos 

 private: System::Void button8_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Ir al Primer Nodo de Todos".

if (header != 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.

current = header;//El primer nodo de todos ("header") pasa a ser el actual.

      //Las siguientes cinco líneas muestran en pantalla el nodo anterior, que gracias a lo que se hizo en la línea anterior se convierte en nuestro nuevo nodo actual.

      textBox1->Text = Convert::ToString(current->edad);
      textBox2->Text = Convert::ToString(current->salario);
      textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

      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.

            textBox3->Text += Char::ToString(current->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.

}

}

 Código del Botón Ir al Último Nodo de Todos 

 private: System::Void button9_Click(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Click del botón "Ir al Último Nodo de Todos".

if (header != 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.

current = header->anterior;//El último nodo de todos (el nodo anterior al "header", pues se está trabajando con el modelo "Circular Doblemente Ligado") pasa a ser el actual.

//Las siguientes dos líneas muestran en pantalla el nodo anterior, que gracias a lo que se hizo en la línea anterior se convierte en nuestro nuevo nodo actual.

      textBox1->Text = Convert::ToString(current->edad);
      textBox2->Text = Convert::ToString(current->salario);
      textBox3->Text="";//Limpia el textBox3 para que no quede nada de procesos anteriores.

      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.

            textBox3->Text += Char::ToString(current->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.

}

}

 Código del Evento Form1_Load 

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {//Código para el evento Form1_Load, es decir cuando se cargue el formulario (siempre que se ejecute el programa).

textBox4->Text = "1";//Para que al cargar el formulario ya aparezca el número 1 en el textBox4 como valor de "k", por si al usuario se le olvida poner un número ahí, que no quede vacío.

}

Universidad Católica de Occidente
El Salvador


AUTOR

Jaime Oswaldo Montoya Guzmán,
Estudiante de tercer año de Ingeniería en Sistemas Informáticos.

jaimemontoya@gmail.com

http://www.geocities.com/jaimemontoya1

Santa Ana, 27 de mayo de 2007

Articulos relacionados:
Las tendencias en los lenguajes de Programación
Resumen:
Intentaremos clarificar estas distinciones tratando diferentes lenguajes de programación en el contexto de cada área de aplicación diferente. El "diseñador del lenguaje" ...
Metodología OMT
Resumen:
Proceso de desarrollo de OMT. Análisis. Diseño del sistema. Mantenimiento. OMT pone énfasis en la importancia del modelo y uso de modelo para lograr una abstracción , en ...
Programación no numérica: GRAFOS
Resumen:
Definición de Grafo. Represenatción. Algoritmo para la búsqueda de anchura. Caminos Mínimos en Grafos. Algoritmo de WARSHALL. De orientación. Topológico. Ejemplos. Gráficos.
Determinantes de Matrices en Visual C++2005
Resumen:
Este trabajo presenta paso a paso el desarrollo de este Programa.
Ingeniería de Sistemas: Catedra Assembler
Resumen:
Componentes Básicos de un Sistema MS -DOS. Arquitectura interna del Intel 80 x 86. Sistemas: Decimal. Binario. Octal. Hexadecimal. Transformaciones. Conversiones. Gráfico...
Copyright © 2011 ilustrados.com, Monografias, tesis, bibliografias, educacion. Tofos los temas y publicaciones son propiedad de sus respectivos autores ©