Qué es un ARCHIVO.??
Altas
Consultas
Bajas
Modificar
Bonus
| VOLVER | |
Arbol | |
Base de Dato | |
Listas | |
Matriz y Vector |
.. ahora si crees que los árboles solo sirven de inodoro para perros y estas de acuerdo con la Caperucita, que afirma que el Lobo la tiene chica...!!!, te puedo demostrar que ..
.. pero si lo anterior te huele mal, solo necesitas..
ARBOL BINARIO CON ARCHIVO
Mi colega virtual si tienes ganas de leer esta page y piensas que al final serás el mismo, creo que te equivocas, por que es factible que contigo ocurran alguna de las siguientes alternativas..
Cualquiera sea tu opinión, me agradaría conocerla...!!!
Tu deseo a mi email personal: wilucha@hotmail.com
o en mi casa: wilucha@ciudad.com.ar
.. ahora si esta WEBada te importa un comino y estas de acuerdo con Robin, que afirma que Batman la tiene chica...!!!, permite que te demuestre que ..
cada tucumano es un paradigma..!!
.. pero si lo anterior te huele mal, solo ponte a..
Vuela tu mente...!! Fuma dinamita..!!!
ARBOL BINARIO
Un árbol binario es un conjunto de elementos que esta vacio o dividido en tres subconjuntos separados.
El primer subconjunto contiene un elemento único llamado la raíz. Los otros dos subconjuntos son por si mismo arboles binarios y se les llama subárboles izquierdo y subárboles derecho.
Cada elemento se denomina nodo. Un Arbol se representa así:
A
/ \
B C
/ \
D E
/ \
F G
Si A es raíz de un árbol binario y B es la raíz del subárbol izquierdo o derecho,
se dice que
A es el padre de B
B es el hijo izquierdo de A,
C será el hijo derecho de A.
Un nodo que no tiene hijos se denomina hoja ej: B, D, F, G de la figura.
El nodo n1 es un ancestro de del nodo n2 (y n2 es descendiente de n1) si n1 es el padre de n2 o el padre de algún ancestro de n2.
Por ejemplo A es un ancestro de F y G es descendiente de C. Dos nodos se dicen hermanos si son los hijos derecho e izquierdo del mismo padre.
Si cada nodo que no es una hoja tiene subárboles izquierdo y derecho que no están vacíos, se llama árbol estrictamente binario.
Un árbol estrictamente binario de n hojas siempre tienen 2n-1 nodos.
El nivel de un árbol se define de la siguiente forma, el nivel de la raíz de un árbol es 0, y el nivel de cualquier otro nodo es uno mas que el de su padre.
La profundidad de un árbol es el máximo nivel de cualquier hoja.
La potencia total de la técnica de asignación dinámica con acceso a través de apuntadores es exhibida en aquellas aplicaciones en las cuales la estructura del árbol mismo varia, es decir crece y/o se contrae durante la ejecución del programa.
RECORRER: el árbol que consta en visitar todos los nodos del árbol. Existen tres ordenamientos principales que surgen en forma natural de las estructuras de los árboles.
Al igual que la estructura de árbol, se expresan en forma recursiva.
1. Preorden : R, A, B (visitar el nodo raíz antes que los subárboles)
2. En orden : A, R, B
3. Postorden :A, B, R (visitar los subárboles antes de la raíz)
|
R
/ \
A B
Los árboles binarios se usan para representar un conjunto de datos cuyos elementos se recuperan a través de una llave única.
Si un árbol se organiza en tal forma que para cada nodo Ti todas las llaves en el subárbol izquierdo de Ti sean menores que la llave Ti, y las llaves del subárbol derechos sean mayores que la llave Ti, entonces ese árbol se llama árbol de búsqueda.
Para comenzar es necesario que registres las declaraciones de las estructuras de tus datos
type Ficha=RECORD Codigo:String[5]; nombre:String[30]; SiEsta:Boolean; end; Nodo=^NodoDeLaLista; NodoDeLaLista=RECORD Codigo:String[5]; EstanEn:Integer; nombre:String[30]; Siguiente:Nodo; Anterior:Nodo; end; PunteroArbol=^NodoDelArbol; NodoDelArbol=RECORD Codigo:String[5]; EstanEn:Integer; nombre:String[30]; RamaDerecha:PunteroArbol; RamaIzquierda:PunteroArbol; end;
Si cuando comí huevos me pateó el hígado, cuando coma hígado... ¿me pateará los huevos?
CREACION DE NODOS
En este link veras la manera de crear un nuevo nodo, cargar sus campos luego grabarlo en un archivo
procedure TMiFormulario.FormCreate(Sender: TObject);
begin
MiFicus:=Nil;
NodoDeLista:=Nil;
OpcionDeCambio:=0;
AssignFILE(Archivo,'DatoPino.dat');
{$I-}
Reset(Archivo);
{$I+}
if ioresult <> 0 then
rewrite(Archivo);
CloseFILE(Archivo);
CargarFicus;
CargarLaLista;
OrdenarLaLista;
end;
procedure TMiFormulario.BotonAltaClick(Sender: TObject);
begin
PanelDatos.Visible:=true;
BotonTopeArriba.Visible:=false;
BotonArriba.Visible:=false;
BotonAbajo.Visible:=false;
BotonTopeAbajo.Visible:=false;
OpcionDeCambio:=1;
ActivarPanelDatos;
LimpiarBoxDatos;
end;
Procedure TMiFormulario.CargarFicus;
begin
Reset(Archivo);
while not eof(Archivo)do
begin
read(Archivo,Registro);
i:=FilePos(Archivo);
InsertarDatoEnNodo(MiFicus,Registro,true);
end;
CloseFile(Archivo);
end;
Procedure TMiFormulario.InsertarDatoEnNodo(var Raiz:PunteroArbol;FichaLeida:Ficha;bandera:Boolean);
begin
if Raiz=nil then
begin
new(Raiz);
Raiz^.RamaDerecha:=nil;
Raiz^.RamaIzquierda:=nil;
Raiz^.codigo:=FichaLeida.codigo;
Raiz^.nombre:=FichaLeida.nombre;
if not bandera then
seek(Archivo,Filesize(Archivo));
Raiz^.EstanEn:=Filepos(Archivo)-1;
end
else
if FichaLeida.Codigo< Raiz^.Codigo then
InsertarDatoEnNodo(Raiz^.RamaIzquierda,FichaLeida,bandera)
else
InsertarDatoEnNodo(Raiz^.RamaDerecha,FichaLeida,bandera);
end;
Procedure TMiFormulario.CargarLaLista;
var
Nuevo:Nodo;
begin
Reset(Archivo);
while not eof(Archivo) do
begin
read(Archivo,Registro);
new(Nuevo);
Nuevo^.Siguiente:=Nil;
Nuevo^.Anterior:=Nil;
Nuevo^.Codigo:=Registro.Codigo;
Nuevo^.nombre:=Registro.nombre;
Nuevo^.EstanEn:=Filepos(Archivo)-1;
if NodoDeLista= Nil then
NodoDeLista:=Nuevo
else
begin
Actual:=NodoDeLista;
while Actual^.Siguiente<>Nil do
Actual:=Actual^.Siguiente;
Actual^.Siguiente:=Nuevo;
Nuevo^.Anterior:=Actual;
end;
end;
end;
Procedure TMiFormulario.OrdenarLaLista;
Var
bandera:Boolean;
Codigo:String[5];
nombre:String[30];
EstanEn:Integer;
begin
if NodoDeLista <> NIL then
repeat
Actual:=NodoDeLista;
bandera:=False;
While(Actual^.Siguiente<>NIL)do
begin
Auxiliar:=Actual^.Siguiente;
if Actual^.Codigo > Auxiliar^.Codigo then
begin
Codigo:=Auxiliar^.Codigo;
nombre:=Auxiliar^.nombre;
EstanEn:=Auxiliar^.EstanEn;
Auxiliar^.Codigo:=Actual^.Codigo;
Auxiliar^.nombre:=Actual^.nombre;
Auxiliar^.EstanEn:=Actual^.EstanEn;
Actual^.Codigo:=Codigo;
Actual^.nombre:=nombre;
Actual^.EstanEn:=EstanEn;
bandera:=true;
end;
Actual:=Actual^.Siguiente;
end;
Until(bandera=false);
end;
Procedure TMiFormulario.PasarDatosFichaANodo(Registro:Ficha);
var
Nuevo:Nodo;
begin
new(Nuevo);
Nuevo^.Codigo:=Registro.Codigo;
Nuevo^.nombre:=Registro.nombre;
Nuevo^.EstanEn:=Filepos(Archivo)-1;
Nuevo^.Siguiente:=nil;
Nuevo^.Anterior:=nil;
if NodoDeLista=nil then
NodoDeLista:=Nuevo
else
begin
Actual:=NodoDeLista;
while Actual^.Siguiente<> nil do
Actual:=Actual^.Siguiente;
Actual^.Siguiente:=Nuevo;
Nuevo^.Anterior:=Actual;
end;
end;
Procedure TMiFormulario.GrabarFichaEnArchivo;
begin
if ElNroDeNodoEs(MiFicus,BoxCodigo.Text)=-1 then
begin
Reset(Archivo);
Registro.Codigo:=BoxCodigo.Text;
Registro.nombre:=BoxNombre.Text;
Registro.SiEsta:=false;
Seek(Archivo,filesize(Archivo));
write(Archivo,Registro);
InsertarDatoEnNodo(MiFicus,Registro,false);
PasarDatosFichaANodo(Registro);
OrdenarLaLista;
CloseFILE(Archivo);
end
else
Application.MessageBox('La Ficha con ese codigo ya existe','Atencion',MB_OKCANCEL);
end;
procedure TMiFormulario.BotonAceptarClick(Sender: TObject);
begin
MiFormulario.Caption:='Estructura Dinamica: Arboles';
PanelDatos.Visible:=false;
CASE (OpcionDeCambio) OF
1:GrabarFichaEnArchivo;
2:
Begin
EliminarNodo(BoxCodigo.Text);
BorradoFisico;
Actual:=NodoDeLista;
while Actual<>Nil do
Begin
NodoDeLista:=Actual^.Siguiente;
Dispose(Actual);
Actual:=NodoDeLista;
end;
NodoDeLista:=Nil;
CargarLaLista;
OrdenarLaLista;
BorrarNodo(MiFicus,BoxCodigo.Text);
end;
3: ModificarFicha(BoxCodigo.Text);
end;
end;
procedure TMiFormulario.BotonGrabarClick(Sender: TObject);
begin
MiFormulario.Caption:='Estructura Dinamica: Arboles';
PanelDatos.Visible:=false;
CASE (OpcionDeCambio) OF
1:GrabarFichaEnArchivo;
2:
Begin
EliminarNodo(BoxCodigo.Text);
BorradoFisico;
Actual:=NodoDeLista;
while Actual<>Nil do
Begin
NodoDeLista:=Actual^.Siguiente;
Dispose(Actual);
Actual:=NodoDeLista;
end;
NodoDeLista:=Nil;
CargarLaLista;
OrdenarLaLista;
BorrarNodo(MiFicus,BoxCodigo.Text);
end;
3: ModificarFicha(BoxCodigo.Text);
end;
end;
¿Por qué no hay comida para gatos 'con sabor a ratón'?
VER NODOS
Recorriendo los nodos del árbol
procedure TMiFormulario.BotonVerClick(Sender: TObject);
var
j:integer;
begin
if BotonVer.Caption='&Grilla' then
begin
BotonVer.Caption:='&Cerrar';
GrillaDeDatos.Visible:=true;
j:=1;
GrillaDeDatos.Cells[0,0]:='Codigo';
GrillaDeDatos.Cells[1,0]:='Nombre';
InOrden(MiFicus,j);
end
else
begin
BotonVer.Caption:='&Grilla';
GrillaDeDatos.Visible:=false;
end;
end;
Procedure TMiFormulario.ActivarPanelDatos;
begin
BoxCodigo.Enabled:=True;
BoxNombre.Enabled:=True;
BoxCodigo.Visible:=True;
BoxCodigo.SetFocus;
end;
PROCEDURE TMiFormulario.LimpiarBoxDatos;
begin
BoxCodigo.text:='';
BoxNombre.text:='';
end;
Procedure TMiFormulario.MostrarBoxConDatos(EstanEn:Integer);
begin
Reset(Archivo);
Seek(Archivo,EstanEn);
Read(Archivo,Registro);
BoxCodigo.Text:=Registro.Codigo;
BoxNombre.Text:=Registro.nombre;
CloseFILE(Archivo);
end;
¿Por qué apretamos más fuerte los botones del control remoto cuando tiene poca batería??
BORRAR NODOS
Ahora te propongo ejemplos de cómo efectuar tanto una baja lógica como una física..
procedure TMiFormulario.BotonBajaClick(Sender: TObject);
begin
PanelDatos.Visible:=true;
BotonTopeArriba.Visible:=true;
BotonArriba.Visible:=true;
BotonAbajo.Visible:=true;
BotonTopeAbajo.Visible:=true;
OpcionDeCambio:=2;
end;
Procedure TMiFormulario.EliminarNodo(CodigoElegido:String);
var
NroDeFicha:Integer;
begin
Reset(Archivo);
NroDeFicha:=ElNroDeNodoEs(MiFicus,CodigoElegido);
If NroDeFicha <> -1 then
Begin
Seek(Archivo,NroDeFicha);
read(Archivo,Registro);
Registro.SiEsta:=true;
if Actual=NodoDeLista then
Begin
NodoDeLista:=Actual^.Siguiente;
NodoDeLista^.Anterior:=nil;
end
else
begin
Auxiliar:=Actual^.Anterior;
Auxiliar^.Siguiente:=Actual^.Siguiente;
if Actual^.Siguiente<>nil then
begin
Auxiliar:=Actual^.Siguiente;
Auxiliar^.Anterior:=Actual^.Anterior;
end;
end;
Dispose(Actual);
Actual:=Auxiliar;
Seek(Archivo,Filepos(Archivo)-1);
write(Archivo,Registro);
BorrarNodo(MiFicus,CodigoElegido);
Application.MessageBox('El dato se borro','ELIMINACION',MB_OK);
end
else
Application.MessageBox('No se encuentra el nodo','ATENCION',MB_OK);
CloseFILE(Archivo);
end;
¿Por qué los Kamikazes usaban cascos.??
CAMBIANDO LOS CAMPOS
Recuerda que solo podrás modificar los campos de datos del nodo, excepto el campo llave ni los punteros a las ramas
procedure TMiFormulario.BotonCambiosClick(Sender: TObject);
begin
PanelDatos.Visible:=true;
ActivarPanelDatos;
BotonTopeArriba.Visible:=true;
BotonArriba.Visible:=true;
BotonAbajo.Visible:=true;
BotonTopeAbajo.Visible:=true;
BoxCodigo.Enabled:=false;
OpcionDeCambio:=3;
end;
Procedure TMiFormulario.ModificarFicha(CodigoElegido:String);
var
NroDeFicha:Integer;
begin
Reset(Archivo);
NroDeFicha:=ElNroDeNodoEs(MiFicus,CodigoElegido);
if NroDeFicha <> -1 then
begin
seek(Archivo,NroDeFicha);
Registro.nombre:=BoxCodigo.Text;
Actual^.Codigo:=BoxCodigo.Text;
Actual^.nombre:=BoxNombre.Text;
write(Archivo,Registro);
CambiarPor(MiFicus,BoxCodigo.Text);
Application.MessageBox('El nodo esta modificado','Cambio de datos',MB_OK);
end
else
Application.MessageBox('Ausencia de datos','El nodo no esta',MB_OK);
CloseFILE(Archivo);
end;
Si un abogado enloquece... ¿pierde el juicio?
CONTANDO NODOS
Cada nodo es único
Function TMiFormulario.ElNroDeNodoEs(Raiz:PunteroArbol;CodigoElegido:String):Integer;
var
Auxiliar:PunteroArbol;
begin
Auxiliar:=Raiz;
while (Auxiliar<>nil)and (Auxiliar^.Codigo<>CodigoElegido)do
begin
if Auxiliar^.Codigo>CodigoElegido then
Auxiliar:=Auxiliar^.RamaIzquierda
else
Auxiliar:=Auxiliar^.RamaDerecha
end;
if Auxiliar<>nil then
begin
ElNroDenodoEs:=Auxiliar^.EstanEn;
end
else
ElNroDeNodoEs:=-1;
end;
Procedure TMiFormulario.CambiarPor(Raiz:PunteroArbol;CodigoElegido:String);
var
Auxiliar:PunteroArbol;
begin
Auxiliar:=Raiz;
while (Auxiliar<>nil)and (Auxiliar^.Codigo<>CodigoElegido) do
begin
if Auxiliar^.Codigo>CodigoElegido then
Auxiliar:=Auxiliar^.RamaIzquierda
else
Auxiliar:=Auxiliar^.RamaDerecha
end;
if Auxiliar<>nil then
begin
Auxiliar^.nombre:=BoxNombre.Text;
end
end;
AUXILIARES
Estos procedimientos los verás en todos tus programas
procedure TMiFormulario.BotonSalirClick(Sender: TObject);
var
opcion:integer;
begin
opcion:=Application.MessageBox('Deseas hacer esto?','Estas por cerrar este programa',MB_OKCANCEL);
if opcion=IDOK then
close;
end;
procedure TMiFormulario.BotonAbajoClick(Sender: TObject);
begin
if Actual^.Siguiente<>nil then
Actual:=Actual^.Siguiente
else
Application.MessageBox('Ojo es la ultima ficha','Tope Bajo',MB_OK);
MostrarBoxConDatos(Actual^.EstanEn);
end;
procedure TMiFormulario.BotonArribaClick(Sender: TObject);
begin
if Actual^.Anterior<>nil then
Actual:=Actual^.Anterior
else
Application.MessageBox('Ojo ya estas en el primero mi ficha','Tope superior',MB_OK);
MostrarBoxConDatos(Actual^.EstanEn);
end;
procedure TMiFormulario.BotonTopeArribaClick(Sender: TObject);
begin
Actual:=NodoDeLista;
MostrarBoxConDatos(Actual^.EstanEn);
end;
procedure TMiFormulario.BotonTopeAbajoClick(Sender: TObject);
begin
While Actual^.Siguiente<>nil do
Actual:=Actual^.Siguiente;
MostrarBoxConDatos(Actual^.EstanEn);
end;
procedure TMiFormulario.BotonVolverClick(Sender: TObject);
begin
PanelDatos.Visible:=false;
end;
IMPRIMIR
Te propongo una manera sencilla de imprimir los datos de tus nodos
procedure TMiFormulario.BotonPrintClick(Sender: TObject);
var
respuesta:integer;
begin
respuesta:=Application.MessageBox('Tu impresora esta prendida?','Atencion',MB_OKCANCEL);
if (respuesta=IDOK)then
PrintDialog.Execute
end;
procedure TMiFormulario.BotonCerrarClick(Sender: TObject);
begin
PanelDatos.Visible:=false;
LimpiarBoxDatos;
end;
VARIABLES GLOBALES
Todo lo anterior requiere que declares tus estructuras..!!
var
MiFormulario: TMiFormulario;
Registro:Ficha;
Archivo:FILE of Ficha;
OpcionDeCambio,i:Integer;
MiFicus:PunteroArbol;
NodoDeLista,Actual,Auxiliar:Nodo;
Procedure ActivarPanelDatos;
Procedure LimpiarBoxDatos;
Procedure GrabarFichaEnArchivo;
Procedure CargarLaLista;
Procedure CargarFicus;
Procedure OrdenarLaLista;
Procedure CambiarPor(Raiz:PunteroArbol;CodigoElegido:String);
Procedure PasarDatosFichaANodo(Registro:Ficha);
Procedure InOrden(Raiz:PunteroArbol;Var j:Integer) ;
Procedure MostrarBoxConDatos(EStanEn:Integer);
Procedure EliminarNodo(CodigoElegido:String);
Procedure ModificarFicha(CodigoElegido:String);
Procedure BorradoFisico;
Procedure BorrarNodo(var LaRamaNodo:PunteroArbol;CodigoElegido:String);
Procedure InsertarDatoEnNodo(var Raiz:PunteroArbol;FichaLeida:Ficha;bandera:Boolean);
Function ElNroDeNodoEs(Raiz:PunteroArbol;CodigoElegido:String):Integer;
Cuando se 'reproduce' un disco... ¿queda 'encinta'?