Qué es esto..??
Altas
Consultas
Bajas
Modificar
Bonus..!!
| Volver | |
Arbol | |
Archivo | |
Base de dato |
Basico | |
Cola y Pila |
| Editor | |
Editor2 | |
Fibonacci | |
Hanoi | |
Listas | |
Matriz |
| Modelo 1 | |
Modelo | |
Polimorfismo |
Punteros | |
Sobrecarga | |
Vectores |
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
PARADIGMA HUMANO
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; }
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..!!
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...
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
//--------------------------------------------------------------------------- __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
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
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
PARADIGMA
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); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- //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
PARADIGMA INFORMATICO
La lógica es un método sistemático de llegar con confianza
... a la conclusión erronea..!!!
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
PARADIGMA HUMANO
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