AGENDA DINAMICA Bienvenido al mundo paradigmático..!!
Un día sin sonrisas es un día perdido..!! PARADIGMA
El hombre se descubre..
... cuando se mide con un obstáculo ..!!
Saint Exupéry

QUE ES.? Qué es esto..??
Clases Altas
Característica Consultas
Clases Bajas
Característica Modificar
Característica Bonus..!!
Diseño | Volver | | Arbol | | Archivo | | Base de dato | Basico | | Cola y Pila |
Comunicación | Editor | | Editor2 | | Fibonacci | | Hanoi | | Listas | | Matriz |
Planificación | Modelo 1 | | Modelo | | Polimorfismo | Punteros | | Sobrecarga | | Vectores |

Un día sin sonrisas es un día perdido..!! PARADIGMA
Todo les sale bién a las personas
de carácter dulce y alegre..!!
Voltaire

Recuerda que las estructuras de datos estáticas, como arreglos requieren necesariamente definir tamaños fijados en tiempo de compilación, mientras que las estructuras dinámicas de datos se expanden o contraen a medida que sean requeridas para su proceso.

Las estructuras dinámicas de datos son colecciones de elementos llamados NODOS, intervinculados por medio de PUNTEROS que permiten estructuras con capacidad de variar su tamaño y ocupar solo la memoria necesaria, creadas y se destruidas durante la ejecución.

Tales nodos de la estructura, generalmente del tipo registro, se enlazan o encadenan de modo que se establece un vículo o puntero asociando a cada nodo, que apunta al nodo siguiente de la estructura.

Existen diferentes tipos de estructuras dinámicas de datos, siendo las más usadas:

PARADIGMA HUMANO
El que un hombre muera por una causa...
..no significa que esta sea verdadera...!!!

Volver al principio


Qué es esto
Variables dinámicas Volver al principio

PARADIGMA HUMANO
La diferencia entre el santo y el pecador...
..es que el santo tiene un pasado y el pecador un porvenir...!!!

LISTA ENLAZADA SIMPLE

Para programarla debemos recordar los siguientes conceptos...

LOS PUNTEROS

Con el fin de simplificar el manejo de punteros, se utilizan nombres de variables en lugar de direcciones, pues los nombres son simples de recordar. Aunque en la realidad, en la máquina cada posición de la pila de memoria tiene una dirección y un valor específico almacenado en esa posición.

Para almacenar un nuevo valor en memoria se asigna a una variable, y la computadora envía una dirección a la memoria seguida por el valor a almacenar en esa posición.

DECLARACION de PUNTEROS

Para declarar un tipo puntero se indica el tipo de valor que se almacenará en la posicion designada por el puntero. Así cada puntero apunta a una variable particular, que es otra posición de memoria.

Dado que el puntero es una variable que registra la dirección de otra variable almacenada en una celda de memoria, es preciso diferenciar entre las dos entidades implicadas en el apuntamiento:

C++, Usa el asterisco (*) que sigue a los nodos, para indicar que "apunta a"; es decir el tipo de dato es una variable puntero que puede contener una dirección a un tipo de dato llamado nodo.

EJEMPLO: Para simplificar el tema, se ha tomado una agenda elemental de dos campos, nombre y email al que se le asignan los mecanismos de altas, bajas, modificaciones y consultas, en el que se incluye los algoritmos de búsqueda.



////////////////////////////////////////////////////////
// C++BUILDER 5               LISTA SIMPLE CON ARCHIV0
//  ListaPrograma.cpp            Wilucha    17/09/98
// Graba sobre en archivo Simple.txt
//---------------------------------------------------------------------------
#include < vcl.h >
#include < fstream.h >
#include < stdlib.h >
#pragma hdrstop
#include "ListaPrograma.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------

TMiFormulario *MiFormulario;

struct MiNodo
{
  char CampoNodoNombre[30];
  char CampoNodoEmail[40];
  int  FlagNodoBaja;
  struct MiNodo *SiguienteNodo;
}

LISTA ENLAZADA VOLATIL

En este link desarrollaremos una agenda sin archivo físico, por lo tanto cuando cierres el programa tus datos se volatilizan.

La lista enlazada es una secuencia de nodos enlazados o conectados con el siguiente formando una estructura de datos dinámica. Tales nodos suelen ser normalmente registros y que no tienen un tamaño fijo.

La ventaja de una lista enlazada sobre un arreglo es que la lista enlazada puede crecer y decrecer en tamaño y que fácil insertar o suprimir un nodo en el centro de una lista enlazada.

La lista enlazada es una estructura muy versátil, cuyos algoritmos para inserción y eliminación de datos constan de dos pasos:

El que en su vida nunca fue necio, jamás fue sabio..!!

PARADIGMA
...Entre el hombre y la mujer no hay amistad posible..
..hay pasión, hostilidad, amor, pero no amistad...!!!


Volver al principio


ALTAS
Enganchando nodos Volver al principio Bienvenido a mi website..!!
PARADIGMA HUMANO
Los jóvenes creen que el dinero lo es todo...
..los viejos lo saben...!!!

METAMOS NODOS en la LISTA

Esta es una tarea divertida, por que me recuerda cuando niño enganchaba un nuevo vagón en mi trencito de juguete..!!. Para ello es necesario tener en cuenta que...

  • LOCOMOTORA..!!..(Primer Nodo)
    Preguntamos si ya hay una. Si no la hay colocamos una sobre la via.. (La Lista..!!)

  • PRIMER VAGON..!!(Segundo Nodo)
    Preguntamos si ya hay una locomotora. Si la hay colocamos una sobre la via.. (La Lista..!!).. luego la enganchamos con la locomotora

  • SEGUNDO VAGON..!!(Tercer Nodo)
    Buscamos el último vagón, o sea el primero. Si lo encontramos, colocamos el segundo vagón sobre la via.. (La Lista..!!).. luego la enganchamos con el último vagón.

  • SIGUIENTE VAGON..!!(Siguiente Nodo)
    Buscamos el último vagón, Si lo encontramos, colocamos este vagón sobre la via.. (La Lista..!!).. luego la enganchamos con el último vagón.

Este proceso ha sido aplicado en el siguiente algoritmo..



////////////////////////////////////////////////////////
// C++BUILDER 5               LISTA SIMPLE SIN ARCHIV0
//  ListaPrograma.cpp            Wilucha    17/09/98
//---------------------------------------------------------------------------

*PrimerNodo,*NodoActual,*NuevoNodo,*UltimoNodo;
 MiNodo *FichaAuxiliar,FichaTrucha;
 int MensajePorBox,ParametroOrdenar,FlagBaja,Fila;
 int BuscarCodigo(AnsiString);

void AltaDeNuevoNodo(char ParamNombre[30],char ParamEmail[40])
{
  NuevoNodo = new MiNodo[sizeof(MiNodo)];
  strcpy(NuevoNodo->CampoNodoNombre,ParamNombre);
  strcpy(NuevoNodo->CampoNodoEmail,ParamEmail);
  NuevoNodo->FlagNodoBaja=0;
  NuevoNodo->SiguienteNodo=NULL;
  UltimoNodo=NuevoNodo;
  if(PrimerNodo==NULL)
      PrimerNodo=NuevoNodo;
    else
     {
       NodoActual=PrimerNodo;
       while(NodoActual->SiguienteNodo != NULL)
             NodoActual=NodoActual->SiguienteNodo;
       NodoActual->SiguienteNodo=NuevoNodo;
     }
}

..Ojito observa que este proceso inserta nuevos nodos en la lista, pero no en el archivo..!!

PARADIGMA HUMANO
La mejor forma de hacer buenos a los niños...
..es hacerlos felices...!!!



//---------------------------------------------------------------------------
__fastcall TMiFormulario::TMiFormulario(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMiFormulario::FormActivate(TObject *Sender)
{
 FlagBaja=0;
}


//---------------------------------------------------------------------------

void __fastcall TMiFormulario::Altas1Click(TObject *Sender)
{
 MiFormulario->Caption="INGRESO DE DATOS";
 Panel->Visible=true;
 BotonGrabar->Visible=true;
 BotonLimpiar->Visible=true;
 BotonEliminar->Visible=false;
 BotonModificar->Visible=false;
 BoxNombre->Clear();
 BoxEmail->Clear();
 BoxNombre->SetFocus();
 Simple1->Enabled=false;
}

//---------------------------------------------------------------------------
void __fastcall TMiFormulario::BotonLimpiarClick(TObject *Sender)
{
 BoxNombre->Clear();
 BoxEmail->Clear();
 BoxNombre->SetFocus();
}

PARADIGMA HUMANO
La única ventaja de jugar con fuego...
..es que aprende uno a no quemarse ...!!!

Por supuesto que los nodos dados de alta están vacios..!!!, por lo tanto veamos cómo les grabamos los datos en cada uno de sus campos...



void __fastcall TMiFormulario::BotonGrabarClick(TObject *Sender)
{
 char Nombre[30], Email[40];
 if((BoxNombre->Text=="")||(BoxEmail->Text==""))
   Application->MessageBox("Introduzca datos","Atencion",MB_OK);
  else
   {
    strcpy(Nombre,BoxNombre->Text.c_str());
    strcpy(Email,BoxEmail->Text.c_str());
    if(BuscarNombre(Nombre)==0)
      {
       AltaDeNuevoNodo(Nombre,Email);
       LlenarCombo();
       BoxNombre->Clear();
       BoxEmail->Clear();
       BoxNombre->SetFocus();
      }
     else
      {
       MensajePorBox=Application->MessageBox("Desea ingresarlo nuevamente","Dato existente",MB_OKCANCEL);
       if(MensajePorBox==IDOK)
         {
          strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str());
          strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str());
          BoxNombre->Clear();
          BoxEmail->Clear();
          BoxNombre->SetFocus();
         }
        else
         {
          BoxNombre->Clear();
          BoxEmail->Clear();
          BoxNombre->SetFocus();
         }
       }
    }
}
//---------------------------------------------------------------------------

Ahora ya tenemos nuestro trencito con los vagones cargados.. Oohh.!! perdón, tenemos la lista enlazada con sus nodos con datos en sus campos.

En los siguientes links, veremos las operaciones más comunes que podemos efectuar con estos nodos.

PARADIGMA HUMANO
Solo hay algo peor que el que hablen de uno..
..es que no hablen...!!!


Volver al principio


CONSULTAS
Ver datos Volver al principio
PARADIGMA
Las lágrimas son el refugio de las chicas feas...
..pero la ruina de las bonitas...!!!

RECORRAMOS LOS NODOS

En este link encontrarás la codificación de los algoritmos para visualizar los datos que cargaste en cada uno de los nodos de tu estructura dinámica.


//---------------------------------------------------------------------------

void __fastcall TMiFormulario::Consultas1Click(TObject *Sender)
 {
   MiFormulario->Caption="Consulta de datos";
   if(PrimerNodo != NULL)
     {
       PanelCombo->Visible=true;
       Combo->Clear();
       BotonGrabar->Visible=false;
       BotonLimpiar->Visible=false;
       BotonEliminar->Visible=false;
       BotonModificar->Visible=false;
       LlenarCombo();
     }
   else
     Application->MessageBox("No hay datos para consultar","Lista Vacia",MB_OK);
}

//---------------------------------------------------------------------------

Te ofrezco un combo..!!



//---------------------------------------------------------------------------

void TMiFormulario::LlenarCombo()
{
 Combo->Clear();
 Combo->Items->Clear();
 NodoActual=PrimerNodo;
 while(NodoActual != NULL)
      {
        Combo->Items->Add(NodoActual->CampoNodoNombre);
        NodoActual=NodoActual->SiguienteNodo;
 }
}


//---------------------------------------------------------------------------
void __fastcall TMiFormulario::BotonAceptarClick(TObject *Sender)
{
 int LoHalle;
 char DatoBuscado[40];
 AnsiString DatoDelCombo;
 LoHalle=0;
 NuevoNodo=PrimerNodo;
 DatoDelCombo=Combo->Items->Strings[Combo->ItemIndex];
 strcpy(DatoBuscado,DatoDelCombo.c_str());
 while(NuevoNodo!=NULL)
 {
  if(stricmp(NuevoNodo->CampoNodoNombre,DatoBuscado)==0)
  {
   LoHalle=1;
   if(NuevoNodo->FlagNodoBaja!=1)
   {
    Panel->Visible=true;
    PanelCombo->Visible=false;
    BoxNombre->Text=NuevoNodo->CampoNodoNombre;
    BoxEmail->Text=NuevoNodo->CampoNodoEmail;
    NodoActual=NuevoNodo;
    NuevoNodo=NULL;
   }
  }
  else
  NuevoNodo=NuevoNodo->SiguienteNodo;
 }
 if(LoHalle==0)
 {
  ShowMessage("La ficha que busca no ha sido ingresada");
  PanelCombo->Visible=false;
 }
}

//---------------------------------------------------------------------------
void __fastcall TMiFormulario::Visualizar1Click(TObject *Sender)
{
 Fila=1;
 if(PrimerNodo==NULL)
 {
  Application->MessageBox("No hay datos en la lista","Atencion...",MB_OK);
 }
 PanelVisualizar->Visible = true;
 if (PrimerNodo!=NULL)
 {
  Grilla->Cells[0][0]="Nombre";
  Grilla->Cells[1][0]="Email";
  NuevoNodo = PrimerNodo;
  while (NuevoNodo->SiguienteNodo!= NULL)
  {
   Grilla->Cells[0][Fila]=NuevoNodo->CampoNodoNombre;
   Grilla->Cells[1][Fila]=NuevoNodo->CampoNodoEmail;
   Fila=Fila+1;
   while ( Grilla->Cells[0][Fila+1]!="")
   {
    Grilla->Cells[0][Fila+1]="";
    Grilla->Cells[1][Fila+1]="";
   }
   NuevoNodo=NuevoNodo->SiguienteNodo;
  }
  Grilla->Cells[0][Fila]=NuevoNodo->CampoNodoNombre;
  Grilla->Cells[1][Fila]=NuevoNodo->CampoNodoEmail;
 }
 else
 {
  PanelVisualizar->Visible = false;
 }
}

PARADIGMA HUMANO
El hombre puede creer lo imposible..
..pero no lo improbable...!!!


Volver al principio


BAJAS
Eliminar datos Volver al principio

PARADIGMA
Las mujeres estan hechas para ser amadas...
..no para ser comprendidas...!!!

BORREMOS NODOS..!!

Si nos equivocamos.. no hay drama..!!, buscamos dónde está el error, lo borramos y a otra cosa.!!!



//---------------------------------------------------------------------------

int BuscarNombre(AnsiString UnNombre)
{
 int HayDato=0;
 NodoActual=PrimerNodo;
 if (NodoActual!=NULL)
    while (NodoActual != NULL)
      {
       if ((UnNombre)==NodoActual->CampoNodoNombre)
          {
           HayDato=1;
           break;
          }
       NodoActual=NodoActual->SiguienteNodo;
      }
 return(HayDato);
}

void __fastcall TMiFormulario::Bajas1Click(TObject *Sender)
{
 MiFormulario->Caption="Eliminacion de datos";
 if(PrimerNodo != NULL)
 {
  PanelCombo->Visible=true;
  BotonGrabar->Visible=false;
  BotonLimpiar->Visible=false;
  BotonModificar->Visible=false;
  BotonEliminar->Visible=true;
  Simple1->Enabled=false;
  LlenarCombo();
  FlagBaja=1;
 }
 else
 Application->MessageBox("No hay datos para eliminar","Lista vacia",MB_OK);
}
//---------------------------------------------------------------------------

PARADIGMA HUMANO
Los viejos creen en todo, los hombres dudan de todo
...los jóvenes lo saben todo..!!!


//---------------------------------------------------------------------------
//BOTON PARA ELIMNAR LOS DATOS
void __fastcall TMiFormulario::BotonEliminarClick(TObject *Sender)
{
 if(PrimerNodo != NULL)
 {
  MensajePorBox=Application->MessageBox("Desea Eliminar estos datos","Eliminacion de datos",MB_OKCANCEL);
  if(MensajePorBox==IDOK)
  {
   FichaAuxiliar=NodoActual;
   if(NodoActual==PrimerNodo)
   PrimerNodo=NodoActual->SiguienteNodo;
   else
   {
    NodoActual=PrimerNodo;
    while(NodoActual->SiguienteNodo != NULL)
    {
     if(NodoActual->SiguienteNodo==FichaAuxiliar)
     {
      FichaTrucha,NodoActual;
      break;
     }
     NodoActual=NodoActual->SiguienteNodo;
    }
    FichaTrucha,FichaAuxiliar->SiguienteNodo;
   }
   delete(FichaAuxiliar);
   LlenarCombo();
   Application->MessageBox("Los datos fueron eliminados","Eliminacion de datos",MB_OK);
  }
 }
 else
 Application->MessageBox("No hay datos a eliminar","La lista HayDato vacia",MB_OK);
 BoxNombre->Clear();
 BoxEmail->Clear();
}
//---------------------------------------------------------------------------

PARADIGMA HUMANO
La sociedad perdona con frecuencia al criminal..
..pero no al soñador...!!!


Volver al principio


MODIFICAR
Cambiar datos Volver al principio

PARADIGMA INFORMATICO
La lógica es un método sistemático de llegar con confianza
... a la conclusión erronea..!!!

CAMBIEMOS DATOS EN LOS NODOS

Si deseas corregir el contenido de un nodo en particular, lo ubicas a este y luego activas el siguiente algoritmo



//---------------------------------------------------------------------------
void __fastcall TMiFormulario::BotonModificarClick(TObject *Sender)
{
 strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str());
 strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str());
 Application->MessageBox("Los datos ya han sido modificados","Modificacion de datos",MB_OK);
 BoxNombre->Clear();
 BoxEmail->Clear();
 BoxNombre->SetFocus();
}

//---------------------------------------------------------------------------
void __fastcall TMiFormulario::Modificaciones1Click(TObject *Sender)
{
 MiFormulario->Caption="Modificacion de datos";
 if(PrimerNodo != NULL)
 {
  PanelCombo->Visible=true;
  Combo->Clear();
  BotonGrabar->Visible=false;
  BotonLimpiar->Visible=true;
  BotonModificar->Visible=true;
  BotonEliminar->Visible=false;
  Simple1->Enabled=false;
  LlenarCombo();
 }
 else
 Application->MessageBox("No hay datos para modificar","Lista vacia",MB_OK);
}

//---------------------------------------------------------------------------

PARADIGMA HUMANO
En la guerra el fuerte hace esclavo al débil..
..en la paz el rico hace esclavo al pobre...!!!


Volver al principio


VARIOS
Accesorios Volver al principio

PARADIGMA HUMANO
Los jóvenes quieren ser fieles y no pueden...
..los viejos quieren ser infieles y no pueden...!!!

BONUS TRACK..!!!

A tu sistema le hará falta los siguientes accesorios...



void __fastcall TMiFormulario::BotonRegresarClick(TObject *Sender)
{
 Panel->Visible=False;
 Simple1->Enabled=true;
 MiFormulario->Caption="Agenda de Wilo";
}


//---------------------------------------------------------------------------
void __fastcall TMiFormulario::BotonVolverClick(TObject *Sender)
{
 PanelVisualizar->Visible=false;
}
//---------------------------------------------------------------------------

void __fastcall TMiFormulario::PorNombre1Click(TObject *Sender)
{
 if(PrimerNodo != NULL)
 {
  Ordenar(ParametroOrdenar);
 }
 else
 Application->MessageBox("No hay datos para ordenar","Lista vacia",MB_OK);
}

void TMiFormulario::Ordenar(int ParametroOrdenar)
{
  if(PrimerNodo!=NULL)
 {
  MiNodo *a,*b,*c;
  if (Application->MessageBox("Se Ordenarán los Elementos de la Lista","ORDENAR",MB_ICONEXCLAMATION+MB_OKCANCEL)==1)
  {
   a=PrimerNodo;
   while(a->SiguienteNodo!=NULL)
   {
    b=a->SiguienteNodo;
    while(b!=NULL)
    {
     if (strcmp(a->CampoNodoNombre,b->CampoNodoNombre)>0)
     {
      c=new(MiNodo);
      strcpy(c->CampoNodoNombre,a->CampoNodoNombre);
      strcpy(c->CampoNodoEmail,a->CampoNodoEmail);
      strcpy(a->CampoNodoNombre,b->CampoNodoNombre);
      strcpy(a->CampoNodoEmail,b->CampoNodoEmail);
      strcpy(b->CampoNodoNombre,c->CampoNodoNombre);
      strcpy(b->CampoNodoEmail,c->CampoNodoEmail);
     }
     b=b->SiguienteNodo;
    }
    a=a->SiguienteNodo;
   }
  }
 }
 else
 {
  Application->MessageBox("No Hay Datos","ORDENAR",MB_DEFBUTTON1+MB_ICONEXCLAMATION);
 }
}

PARADIGMA HUMANO
Es muy fácil convertir a los demás...
..lo difícil es convertirse a sí mismo...!!!


Wilucha: 20-09-02

Volver al principio