ARBOLES en DELPHI Bienvenido al mundo paradigmático..!!
Un día sin sonrisas es un día perdido..!! PARADIGMA
Mi consejo es que te cases:
Si encuentras una buena esposa serás felíz ..
si no, te harás filósofo..!!
Sócrates

QUE ES.? Qué es un ARBOL.??
Clases Altas
Característica Consultas
Clases Bajas
Característica Modificar
Característica Bonus
Diseño | VOLVER | | Archivo | | Base de Dato | | Listas | | Matriz y Vector |

Un día sin sonrisas es un día perdido..!! PARADIGMA
Del árbol del silencio
pende el fruto de la seguridad..!!
Proverbio

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

Te amo..!! tu tésis es un paradigma..!!

Te amo..!! y el aviso también..!!

.. pero si lo anterior te huele mal, solo necesitas..

Gracias a mis hijos..!! Conceder..

GRACIAS A LA VIDA..!! ..dinero..!!

Un día sin sonrisas es un día perdido..!! PARADIGMA
Si lo que vas a decir no es más bello que el silecio
.. no lo digas ..!!
Proverbio

Volver al principio


ARBOLES en DELPHI Volver al principio
Un día sin sonrisas es un día perdido..!! PARADIGMA
Cuando los que mandan pierden la verguenza
Los que obedecen pierden el respeto..!!
Confucio

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
    UnRegistro=record
       CampoNombre,CampoEmail:string;
    end;

    NodoPino=^NodoDeArbol;

    NodoDeArbol=record
        CampoNombre,CampoEmail:string;
        RamaIzquierda,RamaDerecha: NodoPino;
    end;

//////////////////////////////////////
//  PROCEDIMIENTOS SIN PARAMETRO
//////////////////////////////////////
    PROCEDURE NoHayDatos;
    PROCEDURE ActivoPanelAltas;
    PROCEDURE ActivoPanelABM;
    PROCEDURE LimpioLosBoxes;
    PROCEDURE DesabilitoBoxDatos;

//////////////////////////////////////
//  PROCEDIMIENTOS CON PARAMETROS
//////////////////////////////////////
procedure HagoPelotaElNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);

    procedure delete(DatoBuscado:string;var UnNuevoNodo:NodoPino);
    procedure LeoDatosDeBoxes(var FichaLeida:UnRegistro);
    procedure BuscoDatoDeNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);
    procedure ModificoDatoDeNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);
    procedure LimpioGrillaDatos(UnNuevoNodo:NodoPino; var Fila:integer);
    procedure CargoComboConCampoNombre(UnNuevoNodo:NodoPino);
    procedure CargoNodoConDatosFicha(var FichaLeida:UnRegistro; var UnNuevoNodo:NodoPino);
    PROCEDURE InOrden (UnNuevoNodo:NodoPino; VAR Fila:Integer);

var
  MiFormulario: TMiFormulario;
  UnNuevoNodo:  NodoPino;
  FichaLeida:   UnRegistro;
implementation

  1. Si tropiezas dos veces con la misma piedra, Sacala de ahi!
  2. Ultimo momento: Gemelo suicida mata hermano por error.
  3. Curiosa la guitarra, tiene una ceja en el traste.
  4. Si has de beber para olvidar, mejor paga antes de tomar.
  5. Nunca golpees a un hombre con anteojos: usa tus puños!


Volver al principio


ALTAS
Ingreso de nuevos datos Volver al principio

Si tenes ganas de estudiar, sentate hasta que se te pase..!!!

GENERANDO NUEVOS NODOS

Los siguientes procedimientos te permiten cargar datos en los nodos del árbol, pero recuerda que no hay archivo


////////////////////////////////////////////////////////
// Delphi 5  MANEJO DE ARBOLES BINARIOS SIN ARCHIVO
// Wilo Carpio                            31/10/01
////////////////////////////////////////////////////////

procedure TMiFormulario.FormCreate(Sender: TObject);
begin
  UnNuevoNodo:=nil;
end;

///////////////////////////////
//  ALTAS DE NODOS
///////////////////////////////
procedure TMiFormulario.BotonAltasClick(Sender: TObject);
begin
  MiFormulario.Caption := 'REGISTRO DE NUEVO NODO EN EL ARBOL';
  PanelAltas.caption:='Digita los datos, luego Click en Aceptar';
  ActivoPanelAltas;
end;

procedure TMiFormulario.BotonGrabarClick(Sender: TObject);
var
   FichaLeida:UnRegistro;
   DatoBuscado:string;
begin
     if BotonGrabar.caption='&Aceptar' then
        begin
           CargoNodoConDatosFicha(FichaLeida,UnNuevoNodo);
        end
       else
        if BotonGrabar.caption='&Modificar' then
           begin
              ModificoDatoDeNodo(DatoBuscado,UnNuevoNodo);
           end
          else
           if BotonGrabar.caption='&Borrar' then
              begin
                 HagoPelotaElNodo(DatoBuscado,UnNuevoNodo);
              end
end;

procedure TMiFormulario.LeoDatosDeBoxes(var FichaLeida:UnRegistro);
begin
   FichaLeida.CampoNombre:=BoxNombre.text;
   FichaLeida.CampoEmail:=BoxEmail.text;
end;

procedure TMiFormulario.CargoNodoConDatosFicha(var FichaLeida:UnRegistro; var UnNuevoNodo:NodoPino);
begin
 LeoDatosDeBoxes(FichaLeida);
 if FichaLeida.CampoNombre<>'' then  // Si NO se clickeo Grabar sin dato en el box
    begin
        if UnNuevoNodo=nil then      // Si es NO EXISTE un nodo, entonces se
           begin                     // se crea
               new(UnNuevoNodo);     // Un crea un NUEVO NODO y luego se
               UnNuevoNodo^.CampoNombre  := FichaLeida.CampoNombre;  // Carga con datos de la ficha
               UnNuevoNodo^.CampoEmail   := FichaLeida.CampoEmail;
               UnNuevoNodo^.RamaIzquierda:= nil;
               UnNuevoNodo^.RamaDerecha  := nil;
           end
          else                       // Si YA EXISTE un nodo, entonces se
           begin                     // ORDENA como arbol binario
              if UnNuevoNodo^.CampoNombre > FichaLeida.CampoNombre then
                 CargoNodoConDatosFicha(FichaLeida,UnNuevoNodo^.RamaIzquierda)
                else
                 if UnNuevoNodo^.CampoNombre < FichaLeida.CampoNombre then
                    CargoNodoConDatosFicha(FichaLeida,UnNuevoNodo^.RamaDerecha)
                   else
                    showmessage('Ese nombre ya existe');
           end;
        LimpioLosBoxes;
    end
  else   // Si se clickeo Grabar sin dato en el box nombre
   showmessage('Para grabar debes digitar un Nombre...!!!');
end;

procedure TMiFormulario.LimpioLosBoxes;
begin
     BoxNombre.text:='';
     BoxEmail.text:='';
     BoxNombre.SetFocus;
end;

  1. Si, estoy loco... ¿Y qué? Mi manicomio tiene jardín y tu casa no.
  2. Se necesita cama, con muchacha adentro.
  3. A los 15 años era una bomba... a los 25 una reventada.
  4. Si la montaña no viene a mi... seguro que se me paso la curda.
  5. Murio por un pedazo de carne... se arrojo al vacio.


Volver al principio


CONSULTAS
Ver datos Volver al principio

El amor como la gripe siempre terminan en la cama..!!!

VER CONTENIDO DE LOS NODOS

En este link puedes apreciar los procedimientos para recorrer el árbol


/////////////////////////////////////
//  VER POR GRILLA
/////////////////////////////////////
procedure ActivarPanelGrilla;
begin
    MiFormulario.Caption:='GRILLA DE DATOS GRABADOS';
    MiFormulario.PanelGrilla.visible:=True;
    MiFormulario.PanelABM.visible:=False ;
    MiFormulario.MiGrilla.cells[0,0]:='NOMBRE';
    MiFormulario.MiGrilla.cells[1,0]:='EMAIL';
end;

procedure TMiFormulario.BotonGrillaClick(Sender: TObject);
var
   Fila:integer;
begin
 if UnNuevoNodo<>nil then
   begin
     ActivarPanelGrilla;
     Fila:=1;
     InOrden(UnNuevoNodo,Fila);
   end
 else
   NoHayDatos;
end;

PROCEDURE tMiFormulario.InOrden (UnNuevoNodo:NodoPino; VAR Fila:Integer);
BEGIN
     IF UnNuevoNodo<>NIL THEN
       BEGIN
          InOrden (UnNuevoNodo^.RamaIzquierda,Fila);
          MiGrilla.Cells[0,Fila]:=UnNuevoNodo^.CampoNombre;
          MiGrilla.Cells[1,Fila]:=UnNuevoNodo^.CampoEmail;
          IF Fila=MiGrilla.rowcount THEN
            MiGrilla.rowcount:=MiGrilla.rowcount+1;
          Fila:=Fila+1;
          InOrden (UnNuevoNodo^.RamaDerecha,Fila);
       END;
END;

procedure TMiFormulario.CerrarGrillaClick(Sender: TObject);
var
   Fila:integer;
begin
     Fila:=1;
     LimpioGrillaDatos(UnNuevoNodo,Fila);
     ActivoPanelABM;
end;
  1. Soy vegetariana por eso fumo marihuana.
  2. La mujer que no tiene suerte con los hombres no sabe la suerte que tiene.
  3. La esclavitud no se abolio se cambio a 8 horas de clase.
  4. Si esta pared es el limite de su propiedad, dejenos decorar sus limitaciones.
  5. Si la montaña viene hacia a ti... corre boludo! es un derrumbe!


Volver al principio


BAJAS
Eliminar datos Volver al principio

Qué cuentan las ovejas para poder dormir..!!!

ELIMINACION DE NODOS

Este link te muestra como sacar de la memoria el contenido del nodo


//////////////////////////////////
//       BAJAS
//////////////////////////////////
procedure TMiFormulario.BotonBajaClick(Sender: TObject);
begin
   if UnNuevoNodo<>nil then
    begin
      MiFormulario.Caption:='BORRANDO EL CONTENIDO DEL NODO';
      PanelAltas.caption:='Selecciona Nombre en el combo';
      ActivoPanelAltas;
      BotonGrabar.caption:='&Borrar';
      CargoComboConCampoNombre(UnNuevoNodo);
      ComboNombre.visible:=true;
      DesabilitoBoxDatos;
    end
   else
    NoHayDatos;
end;

procedure TMiFormulario.HagoPelotaElNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);
begin
  if (application.MessageBox('¿Deseas hacerlo?','ESTAS POR HACER PELOTA UN NODO', mb_iconquestion+mb_YESNO+mb_defbutton2)) = idYES  then
     begin
       DatoBuscado:=ComboNombre.text;
       delete(DatoBuscado,UnNuevoNodo);
       ActivoPanelABM;
     end;
end;

procedure tMiFormulario.delete(DatoBuscado:string;var UnNuevoNodo:NodoPino);
 var
   NodoActivo:NodoPino;
 procedure del(var NodoCopia:NodoPino);
   begin
        if NodoCopia^.RamaDerecha<>nil then
           del(NodoCopia^.RamaDerecha)
         else
          begin
            NodoActivo^.CampoNombre:=NodoCopia^.CampoNombre;
            NodoActivo^.CampoEmail:=NodoCopia^.CampoEmail;
            NodoActivo:=NodoCopia;
            NodoCopia:=NodoCopia^.RamaIzquierda;
          end;
   end;
 begin
   if UnNuevoNodo=nil then
        ShowMessage('No existe')
      else
        if DatoBuscadoUnNuevoNodo^.CampoNombre then
                 delete(DatoBuscado,UnNuevoNodo^.RamaDerecha)
                else
                 if DatoBuscado=UnNuevoNodo^.CampoNombre then
                    begin
                      NodoActivo:=UnNuevoNodo;
                      if NodoActivo^.RamaDerecha=nil then
                         UnNuevoNodo:=NodoActivo^.RamaIzquierda
                        else
                         if NodoActivo^.RamaIzquierda=nil then
                            UnNuevoNodo:=NodoActivo^.RamaDerecha
                           else
                            del(NodoActivo^.RamaIzquierda)
                    end;
end;

  1. Las ideas no se matan...se afanan.
  2. Esdificilsercreativoconsolo72caracteres
  3. peromasdificillofueconsolo50
  4. El que rie al último no entendió el chiste.
  5. Estudiar es desconfiar de la inteligencia del compañero de al lado.


Volver al principio


MODIFICAR
Cambiar datos Volver al principio

Me las pagarán..!!! ( FMI )

MODIFICACIONES

Recuerda que solo puedes cambiar el contenido de los campos de datos del nodo, no así el campo llave ni los que contienen los punteros.


//////////////////////////////////
//  MODIFICACIONES
//////////////////////////////////
procedure TMiFormulario.BotonCambiosClick(Sender: TObject);
begin
  if UnNuevoNodo<>nil then
   begin
     MiFormulario.Caption:='MODIFICACION DEL CONTENIDO DEL NODO';
     PanelAltas.caption:='Selecciona un nombre en el combo';
     ActivoPanelAltas;
     BotonGrabar.caption:='&Modificar';
     ComboNombre.visible:=true;
     CargoComboConCampoNombre(UnNuevoNodo);
   end
  else
   NoHayDatos;
end;

procedure TMiFormulario.ModificoDatoDeNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);
begin
   ComboNombre.visible:=true;
   DatoBuscado:=ComboNombre.text;
   if UnNuevoNodo <> nil then
      begin
         if UnNuevoNodo^.CampoNombre = DatoBuscado then
             if (application.MessageBox('¿Deseas guardarlos?','MODIFICACION DE DATOS DEL NODO', mb_iconquestion+mb_YESNO+mb_defbutton2)) = idYES  then
                begin
                    UnNuevoNodo^.CampoNombre:=UnNuevoNodo^.CampoNombre;
                    UnNuevoNodo^.CampoEmail:= BoxEmail.text;
                end;
          ModificoDatoDeNodo(DatoBuscado,UnNuevoNodo^.RamaDerecha);
          ModificoDatoDeNodo(DatoBuscado,UnNuevoNodo^.RamaIzquierda);
       end;
    ActivoPanelABM;
end;

  1. Si eres rico, tengo mucho gusto en conocerte.
  2. Si estudiar hace grande al hombre, que estudien los petisos.
  3. El que sabe sabe... y el que no sabe es jefe.
  4. Yo no sufro de locura... la disfruto a cada minuto.
  5. El Bambino está en el bar comiendo un pebete.
  6. Nada en vano, todo en vino.


Volver al principio


VARIOS
Accesorios Volver al principio

Soy un quemo..!!! ( Nerón )

BUSCAR y VER TEORIA

Te recomiendo que en este link aprendas a usar el fantástico combo box, que te simplificará tus tareas de modificar y borrar nodos.


//////////////////////////////
//  BUSQUEDA
//////////////////////////////
procedure TMiFormulario.BotonBuscarClick(Sender: TObject);
var
   DatoBuscado:string;
begin
  if UnNuevoNodo<>nil then
   begin
     MiFormulario.Caption:='BUSQUEDA DEL CONTENIDO DEL NODO';
     DatoBuscado:=ComboNombre.text;
     BuscoDatoDeNodo(DatoBuscado,UnNuevoNodo);
     PanelAltas.caption:='Selecciona un nombre en el combo';
     ActivoPanelAltas;
     DesabilitoBoxDatos;
     BotonGrabar.visible:=false;
     ComboNombre.visible:=true;
     CargoComboConCampoNombre(UnNuevoNodo);
   end
  else
   NoHayDatos;
end;

procedure tMiFormulario.BuscoDatoDeNodo(var DatoBuscado:string;var UnNuevoNodo:NodoPino);
begin
     if UnNuevoNodo <> nil then
        begin
             if UnNuevoNodo^.CampoNombre = DatoBuscado then
                begin
                     BoxNombre.text:=UnNuevoNodo^.CampoNombre;
                     BoxEmail.text:=UnNuevoNodo^.CampoEmail;
                end;
             BuscoDatoDeNodo(DatoBuscado,UnNuevoNodo^.RamaIzquierda);
             BuscoDatoDeNodo(DatoBuscado,UnNuevoNodo^.RamaDerecha);
        end;
end;

procedure TMiFormulario.CargoComboConCampoNombre(UnNuevoNodo:NodoPino);
begin
     IF UnNuevoNodo<>NIL THEN
       BEGIN
          CargoComboConCampoNombre (UnNuevoNodo^.RamaIzquierda);
          ComboNombre.items.add(UnNuevoNodo^.CampoNombre);
          CargoComboConCampoNombre(UnNuevoNodo^.RamaDerecha);
       end;
end;

procedure tMiFormulario.LimpioGrillaDatos(UnNuevoNodo:NodoPino; var Fila:integer);
BEGIN
     IF UnNuevoNodo<>NIL THEN
        BEGIN
           LimpioGrillaDatos(UnNuevoNodo^.RamaIzquierda,Fila);
           MiGrilla.Cells[0,Fila]:='';
           MiGrilla.Cells[1,Fila]:='';
           IF Fila=MiGrilla.rowcount THEN
              MiGrilla.rowcount:=MiGrilla.rowcount+1;
           Fila:=Fila+1;
           LimpioGrillaDatos(UnNuevoNodo^.RamaDerecha,Fila);
       END;
END;

procedure TMiFormulario.BotonCerrarClick(Sender: TObject);
begin
    if (BotonGrabar.Visible=True) and (BotonGrabar.caption='&Aceptar') and (BoxNombre.text<>'') then
        if (application.MessageBox('¿Deseas guardarlos?','DIGITASTE DATOS EN PANTALLA', mb_iconquestion+mb_YESNO+mb_defbutton2)) = idYES  then
           begin
              LeoDatosDeBoxes(FichaLeida);
              if FichaLeida.CampoNombre<>'' then
                  CargoNodoConDatosFicha(FichaLeida,UnNuevoNodo);
           end
         else
           begin
              ActivoPanelABM;
           end
    else
     begin
       ActivoPanelABM
     end;
end;

procedure TMiFormulario.ComboNombreChange(Sender: TObject);
var
   DatoBuscado:string;
begin
     DatoBuscado:=ComboNombre.text;
     BuscoDatoDeNodo(DatoBuscado,UnNuevoNodo);
end;


//////////////////////////////////////
//  PROCEDIMIENTOS VER POR GRILLA
//////////////////////////////////////
PROCEDURE TMiFormulario.NoHayDatos;
BEGIN
  application.messagebox('Aún no ingresaste ningún dato', 'ESTRUCTURA VACIA', mb_iconexclamation+mb_OK+ mb_defbutton1);
  ActivoPanelABM;
END;

procedure TMiFormulario.ChauMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 if (application.MessageBox('¿Deseas Salir del Programa?','ESTAS POR CERRAR ESTE SISTEMA', mb_iconquestion+mb_YESNO+mb_defbutton2)) = idYES  then
    begin
      close();
    end;
end;

//////////////////////////////////////
//  PROCEDIMIENTOS ACTIVAR PANELES
//////////////////////////////////////
PROCEDURE TMiFormulario.ActivoPanelABM;
BEGIN
  MiFormulario.Caption:='PROGRAMA MODELO DELPHI: Arbol sin archivo     Wilo Carpio';
  PanelABM.visible:=True ;
  PanelGrilla.visible:=False ;
  PanelTeoria.visible:=False ;
  PanelAltas.visible:=False;
  BoxNombre.enabled:=true;
  BoxEmail.enabled:=true;
  ComboNombre.text:='';
END;

PROCEDURE TMiFormulario.DesabilitoBoxDatos;
BEGIN
  BoxNombre.enabled:=false;
  BoxEmail.enabled:=false;
END;

PROCEDURE TMiFormulario.ActivoPanelAltas;
BEGIN
  PanelABM.visible:=False ;
  PanelGrilla.visible:=False ;
  PanelTeoria.visible:=False ;
  PanelAltas.visible:=True;
  BoxNombre.enabled:=true;
  BoxEmail.enabled:=true;
  ComboNombre.Items.Clear;
  ComboNombre.text:='';
  LimpioLosBoxes;
  ComboNombre.visible:=false;
  BotonGrabar.caption:='&Aceptar';
  BotonGrabar.visible:=true;
END;


procedure TMiFormulario.BotonTeoriaClick(Sender: TObject);
begin
     PanelTeoria.visible:=True;
     PanelABM.visible:=False;
     Autor.visible:=True;
end;

procedure TMiFormulario.CerrarAutorClick(Sender: TObject);
begin
  PanelABM.visible:=true;
  PanelTeoria.visible:=False;
end;

  1. No hay mujer fea solo belleza rara.
  2. No estoy en contra de que haya hombres feos, pero porque todos viene en esta cuidad.
  3. La pereza es la madre de todos los vicios, y como a la madre hay que respetarla...
  4. Estoy preñado de ideas pero no las puedo parir.
  5. Si su niño llora, dele coca cola y si sigue llorando dele con la botella.
  6. En este mundo todo lo bueno, o es pecado, o engorda, o preña.


Volver al principio