PDA

Ver la Versión Completa : Ordenar e insertar ordenado en TObjectList


sebamawa
16-08-2012, 17:56:16
Hola a todos.

Me estoy iniciando en Delphi y me gustaría saber como ordenar una lista TObjectList según un campo clave de los objetos insertados en la lista. Leí por algún lado que se dispone del método Sort, pero no tengo claro su utilización.

Además me gustaría saber si hay algún método para insertar un objeto de forma ordenada en una lista TObjectList, también con respecto a un campo (propiedad) clave del objeto a insertar.

Muchas gracias.

Saludos.

roman
16-08-2012, 18:29:49
El método Sort de TObjectList recibe como parámetro una función (que tú defines) que le indica cómo debe comparar tus objetos. La función debe devolver un número positivo si el primer objeto es "mayor" que el primero, 0 si son iguales y un número negativo si el primer objeto es "menor" que el segundo.

Te pongo un ejemplo:


// Clase de los objetos que conforman la lista
TCliente = class
Nombre: String;
Telefono: String;
end;

// Función para comparar dos objetos (en este caso, compara los clientes por su nombre)
function ComparaClientes(Item1, Item2: Pointer): Integer;
begin
if TCliente(Item1).Nombre > TCliente(Item2).Nombre then
Result := 1 // > 0
else if TCliente(Item1).Nombre = TCliente(Item2).Nombre then
Result := 0
else
Result := -1 // < 0;
end;

// Ejemplo de uso:
Lista.Sort(ComparaClientes);


Me parece que TObjectList no tiene forma de insertar ordenadamente.

// Saludos

sebamawa
16-08-2012, 19:00:50
Gracias roman por tu respuesta.
Al hacer el llamado con (según tu ejemplo):
Lista.Sort(ComparaClientes);el IDE me dice que no le estoy pasando la cantidad correcta de parámetros a la función ComparaClientes.
¿Cuál es el problema?. Yo vengo de Pascal estándar, y estoy aprendiendo no hace tanto programación a objetos. Para mi habría que pasarle a la función dos punteros como parámetros, pero en este caso tal vez no sea así.

Otra pregunta, ¿ se dispone en Delphi de alguna lista "dinámica" predefinida para insertar objetos de forma ordenada ?.

Muchas gracias.

Saludos.

roman
16-08-2012, 19:10:59
Para mi habría que pasarle a la función dos punteros como parámetros

No, porque entonces estarías pasando al método Sort el resultado de comparar dos objetos en específico. El parámetro de Sort es una función (no el resultado de una función). Pasar funciones o procedimientos como parámetros se usa desde el pascal estándar.

Necesitaría ver el código exacto que estás usando para ver porqué el compilador te marca ese error.

// Saludos

sebamawa
16-08-2012, 19:48:52
Entiendo roman, es clara tu explicación y mala mi interpretación previa.
Haber si con parte del código se logra detectar el error.

En una unidad (UPersona) declaro un objeto persona de la siguiente forma:

TPersona = class
private
documento: Integer;
nombre: String;
public
(* Constructores *)
Constructor Create(doc: Integer; nom: String);

(* Selectoras *)
Function GetDocumento: Integer;
Function GetNombre: String;

(* Modificadoras *)
Procedure SetDocumento(doc: Integer);
Procedure SetNombre(nom: String);
end;

implementation
...
end.Luego en un TForm aparecen estos procedimientos asociados a dos botones.
Primero declaro las variables
var
Form1: TForm1;
p: TPersona;
listaPersonas: TObjectList; Primer botón:

procedure TForm1.Button1Click(Sender: TObject);
begin
p:=TPersona.Create(StrToInt(Edit1.Text),Edit2.Text);
listaPersonas:=TObjectList.Create(True);

// Agregamos el objeto persona a la lista
listaPersonas.Add(p);

Edit1.Text:='';
Edit2.Text:='';
end; La idea es que cada vez que se presiona el botón Button1 se agrege un objeto persona a la lista TObectList, cuyos campos (documento y nombre) se leen desde dos TEdits.

Ahora el segundo botón:

procedure TForm1.Button2Click(Sender: TObject);
function OrdenarPorDocumento(a: Pointer;b: Pointer): Integer;
begin
if TPersona(a).GetDocumento > TPersona(b).GetDocumento then
result:=-1
else
if TPersona(a).GetDocumento < TPersona(b).GetDocumento then
result:=1
else
result:=0;
end;

begin
ListaPersonas.Sort(OrdenarPorDocumento);
end; La idea es que cuando se apreta el segundo botón (Button2) se ordene la lista.

Desde ya muy agredecido por cualquier comentario.

Saludos.

roman
16-08-2012, 20:06:47
Así, a bote pronto, lo único que se me ocurre es que declares la función OrdenarPorDocumento fuera del evento Button2Click. Es posible que los procedimientos locales no se puedan pasar como parámetros. Nunca lo he intentado.

// Saludos

sebamawa
16-08-2012, 20:26:37
Gracias roman por tu orientación.
Veré si puedo solucionar el problema.
Saludos.

roman
16-08-2012, 22:21:08
Desempolvando los algoritmos de inserción binaria, podemos hacer una rutina que inserte los objetos en orden:


procedure InsertaOrdenado(Lista: TObjectList; Comparar: TListSortCompare; Item: Pointer);
var
Primero, Ultimo, Central, Resultado: Integer;

begin
Primero := 0;
Ultimo := Lista.Count - 1;

while Primero <= Ultimo do
begin
Central := (Primero + Ultimo) div 2;
Resultado := Comparar(Item, Lista[Central]);

if Resultado < 0
then Ultimo := Central - 1
else Primero := Central + 1;
end;

Lista.Insert(Primero, Item);
end;


Por ejemplo, puedes definir la función comparadora:


function CompararDocumentos(P1, P2: Pointer): Integer;
begin
if TPersona(P1).Documento > TPersona(P2).Documento then
Result := 1
else if TPersona(P1).Documento = TPersona(P2).Documento then
Result := 0
else
Result := -1;
end;


al momento de insertar:


P := TPersona.Create(StrToIntDef(txtDocumento.Text, 0), txtNombre.Text);
InsertaOrdenado(ListaPersonas, CompararDocumentos, P);


// Saludos

sebamawa
17-08-2012, 09:33:58
Excelente roman. Personalmente yo usaba búsqueda e inserción binaria en Pascal estándar con arreglos (listas estáticas), pero no con listas dinámicas (listas enlazadas). El hecho de tener en TObjectList un campo que indiza cada nodo facilita mucho las cosas.

Por otro lado, el inconveniente que tenia con la función comparadora lo solucioné con el llamado
Lista.Sort(@ComparaClientes);
en lugar de
Lista.Sort(ComparaClientes);
tomando el llamado de tu ejemplo del principio.

Saludos.

Neftali [Germán.Estévez]
17-08-2012, 09:55:42
Otra opción que a veces utilizo yo y que resulta más rápida de implementar, aunque es posible que no tan eficiente, cuando se requiere algo similar a lo que planteas (objetos + campo de ordenación) es utilizar un TStringList.

Utilizo el campo como String (para definir la ordenación) y los objetos se almacenan en la propiedad Objects.
Sólo se puede utilizar si la conversión del campo se puede hacer a un string y la ordenación de este tipo es la correcta para el resultado esperado.


var
TS:TStringList;
key:String;
begin

TS := TStringList.Create;
TS.Sorted := True;
TS.Duplicates := dupError; // esto dependiendo de lo que se necesite

...

// Añadir
key := <-- Campo clave para ordenación
i := TS.AddObject(key, obj)
...

ecfisa
17-08-2012, 13:52:27
Hola.

Hice unas pruebas y si la función pasada como argumento está fuera del procedimiento/función (que es como la he usado anteriormente) se la puede llamar:

Lista.Sort(Compare);


Ahora, enviando como argumento la dirección de la función como menciona sebamawa, y figura en el ejemplo de la ayuda de Delphi:

Lista.Sort(@Compare);

la llamada trabaja tanto si la función es anidada como si es externa.


También es muy interesante tu enfoque Neftali ;)

Saludos.:)

roman
17-08-2012, 17:17:29
Por otro lado, el inconveniente que tenia con la función comparadora lo solucioné con el llamado
Lista.Sort(@ComparaClientes);
en lugar de
Lista.Sort(ComparaClientes);
tomando el llamado de tu ejemplo del principio.


¿Qué versión de Delphi usas?

// Saludos

roman
17-08-2012, 17:43:12
Otra opción que a veces utilizo yo y que resulta más rápida de implementar, aunque es posible que no tan eficiente, cuando se requiere algo similar a lo que planteas (objetos + campo de ordenación) es utilizar un TStringList.


En realidad, yo casi siempre termino usando un TStringList precisamente por lo que dices. Es de lo más común que un objeto tenga un identificador natural de tipo cadena, además de que el TStringList también permite la ordenación personalizada con el método CustomSort. Desafortunadamente, la inserción ordenada sólo es posible para la ordenación regular. Claro que, ya bien visto, la rutina que puse para el TObjectList puede adaptarse para el TStringList.

En otro tenor de cosas, no sé si el compañero sebamawa ha considerado el uso de una bse de datos. A veces se enreda uno implementando estructuras de datos para guardar información que perfectamente podría manejarse con una base.

// Saludos

sebamawa
17-08-2012, 18:08:33
Estimados amigos, agradezco de sobremanera la ayuda y las sugerencias proporcionadas por parte de ustedes.

Respecto a
En otro tenor de cosas, no sé si el compañero sebamawa ha considerado el uso de una bse de datos. A veces se enreda uno implementando estructuras de datos para guardar información que perfectamente podría manejarse con una base.les comento que como menciono al principio de este hilo me estoy iniciando en Delphi, mi base previa es Pascal estándar. Por eso foros como este son de mucha ayuda para mi. Y respecto a la utilización de base de datos, todavía no llego a tanto jeje. Tal vez sea algo relativamente sencillo de implementar, pero por ahora estoy tratando de migrar algunas estructuras de Pascal estándar a Delphi, aunque tal vez no sea la mejor idea a veces según me da a entender roman.

Ya que estoy en este tema, me podrán recomendar un buen manual de Delphi donde pueda estudiar. Si estuviera su versión digital para descarga sería fantástico.

Gracias y saludos.

roman
17-08-2012, 18:19:18
Ya que estoy en este tema, me podrán recomendar un buen manual de Delphi donde pueda estudiar. Si estuviera su versión digital para descarga sería fantástico.


¡Claro! En nuestro Repositorio de archivos (http://terawiki.clubdelphi.com/) hay mucho material. Busca en Delphi/Manuales. Entre otros, encontrarás La cara oculta de delphi 4, que en gran medidad, sigue vigente aún para las versiones actules de delphi.

// Saludos

roman
17-08-2012, 18:21:27
¡Ah! También está el mismo libro pero para la versión 6. Tiene su título en inglés (The Dark Side of Delphi) pero el libro está en español.

// Saludos

Delphius
17-08-2012, 20:46:00
Roman tengo una duda sobre tu propuesta, que dicho sea de paso, es altamente ingeniosa como acostumbras.
La inserción binaria, al menos lo que yo tengo entendido y recuerdo de cátedra (de hace ya años...) sólo tiene sentido si la lista ya está está ordenada. Es decir que para poder insertar de forma ordenada, se debe ejecutar el método Sort() previamente.
No si es que he analizado mal el algoritmo que propones, pero creo ese InsertaOrdenado() falla cuando se intenta insertar el 1er item y el vez de colocarlo en el índice 0, va a parar en el índice 1.

Como nota: No sería de extrañar que en las nuevas versiones de Delphi el algoritmo de ordenamiento "base" o "kernel" de TList deje de ser QuickSort. Existe un algoritmo, relativamente reciente, que es más rápido y además permite hacer inserciones de forma directa. Se llama TimSort (http://en.wikipedia.org/wiki/Timsort). Java, Python ya lo tienen implementado como el algoritmo de ordenamiento por defecto en sus últimas versiones.

Por otro lado nada impide hacer un TOrderObjectList que implemente justamente tanto ordenamiento como inserción ordenada.

Saludos,

roman
17-08-2012, 21:00:46
La inserción binaria, al menos lo que yo tengo entendido y recuerdo de cátedra (de hace ya años...) sólo tiene sentido si la lista ya está está ordenada.


Así es. Por eso hay que usarla desde el principio ;). Cuando la lista está vacía, no hay nada qué ordenar y por tanto llamar a Sort está de más. Pero si se intenta usar sobre una lista desordenada, ciertamente hay que llamar a Sort primero.


No si es que he analizado mal el algoritmo que propones, pero creo ese InsertaOrdenado() falla cuando se intenta insertar el 1er item y el vez de colocarlo en el índice 0, va a parar en el índice 1.


Si la lista está vacía, Primero = 0 y Ultimo = -1 así que el ciclo while no se ejecuta y se hace la inserción en el índice 0.


Existe un algoritmo, relativamente reciente, que es más rápido y además permite hacer inserciones de forma directa.


No entiendo que significa que un algoritmo de ordenamiento permita hacer inserciones directas.


Por otro lado nada impide hacer un TOrderObjectList que implemente justamente tanto ordenamiento como inserción ordenada.


Así es, sería lo óptimo, pero hice el procedimiento para facilitar las cosas y no tener que implementar una clase derivada.

// Saludos

Delphius
17-08-2012, 21:22:20
Así es. Por eso hay que usarla desde el principio ;). Cuando la lista está vacía, no hay nada qué ordenar y por tanto llamar a Sort está de más. Pero si se intenta usar sobre una lista desordenada, ciertamente hay que llamar a Sort primero.

Es que a como entendí de las palabras de sebamawa es que quería evitarse el ordenamiento y hacer inserciones ordenadas directamente sobre la lista, con los datos previamente almacenados.



Si la lista está vacía, Primero = 0 y Ultimo = -1 así que el ciclo while no se ejecuta y se hace la inserción en el índice 0.

Marche unos lentes para Delphius... no vi ese .Count -1 :o



No entiendo que significa que un algoritmo de ordenamiento permita hacer inserciones directas.

Si... admito que lo dije muy flojo y que no se entendería bien... Como TimSort() es un algoritmo híbrido, posee una combinación del Merge() con Insertion() por lo que posee la particularidad de ofrecer internamente una insercción ordenada.
Con TimSort, de lo poco que le entendí de su funcionamiento, es capaz de determinar cuando aplicar un Merge() y cuando aprovechar una insercción. Si se tuviera TimSort por defecto, al hacer un Add, Insert, Move, etc de forma "automática" se hacen las cosas con un único algoritmo y es posible que en ningún momento se ejecute la parte del Merge().



Así es, sería lo óptimo, pero hice el procedimiento para facilitar las cosas y no tener que implementar una clase derivada.
// Saludos
No sería extraño que en las nuevas versiones ya existiera una clase como esta. Lo más "cercano" a ésta que veo en D6 es TOrderedList, la clase base para TStack y TQueue, que ofrece el método virtual y abstracto PushItem() que está pensado para determinar como ha de tener lugar la inserción del ítem. Tanto TStack como TQueue sobrescriben a éste para conseguir la inserción por pila y cola respectivamente.

Saludos,

roman
17-08-2012, 21:29:25
Es que a como entendí de las palabras de sebamawa es que quería evitarse el ordenamiento y hacer inserciones ordenadas directamente sobre la lista


Eso mismo entendí yo.


con los datos previamente almacenados.


Bueno, es que esto sería imposible ;)

// Saludos

Delphius
17-08-2012, 21:53:56
Bueno, es que esto sería imposible ;)
// Saludos
Pues si. Pero es que yo asumía que por "previamente almacenados" hace referencia a que de algún modo se recuperaban los datos almacenados físicamente y que éstos ya se encontraban ordenados.

Voy a tener que dejar los supuestos :p

Yo también le apuesto a TStringList cuando se trata de mantener los objetos ordenados de acuerdo a cierta "clave", aunque no me es de total agrado... Lo siento como que se está utilizando un parche. :o
Resulta extraño que no hubiera de fábrica una lista de objetos ordenada, sin tener que recurrir a otra vía.

Saludos,

roman
17-08-2012, 22:10:30
Pero, ¿dónde leiste eso de previamente almacenados?

// Saludos

Delphius
17-08-2012, 22:20:21
Pero, ¿dónde leiste eso de previamente almacenados?
// Saludos
Pues por eso... yo asumí que el máximo objetivo, no comentado, de sebamawa era de lograr tener los objetos almacenados y ordenados. De modo que ante una recuperación o "lectura" de éstos, bastaría con hacer una inserción ordenada y no tener que estar aplicando algoritmos de ordenamiento.

Saludos,

roman
17-08-2012, 22:33:17
Pues sí, ése es su objetivo. Creo que te hace falta un café para despertar :p

// Saludos

Delphius
18-08-2012, 01:23:42
Pues sí, ése es su objetivo. Creo que te hace falta un café para despertar :p
// Saludos
Mas bien dejar de jugar al God of War II en la PS2 y postear al mismo tiempo. :D

Saludos,

sebamawa
28-08-2012, 09:52:50
Hola a todos nuevamente !!!
Para eliminar un objeto de una lista TObjectList tenemos el método Remove; ahora para buscar un objeto en la misma por un campo clave hay algún método predefinido?. En caso de no haberlo, sería viable implementar un procedimiento que realice una búsqueda binaria, como propuso Roman para la inserción de objetos en una lista ?
Me podrían poner un ejemplo de este caso, por ejemplo si se tiene una lista de objetos (persona) y se quiere eliminar una persona según un número de documento que se ingrese para la búsqueda. Tengan presente que la lista está ordenada de forma ascendente según los números de documentos.
Desde ya muchas gracias.
Saludos.

ecfisa
28-08-2012, 14:03:53
Hola sebamawa.

Si la lista ya está ordenada podes usar una búsqueda binaria. Tomemos como ejemplo una reducción de la clase que puso de ejemplo roman:

implementation

type
TCliente = class
Nombre: String;
end;

var
LstObj : TObjectList;
Cliente : TCliente;

procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
LstObj := TObjectList.Create;
// Demás operaciones de carga
...
end;

function TForm1.BinarySearch(OLst: TObjectList; Valor: string): Integer;
var
Pri, Ult, Med : Integer;
Esta : boolean;
begin
Pri := 0;
Ult := OLst.Count-1;
Esta := False;
while (Pri <= Ult) and not Esta do
begin
Med := (Pri + Ult) div 2;
if TCliente(OLst.Items[Med]).Nombre = Valor then Esta := true;
if TCliente(OLst.Items[Med]).Nombre < Valor then Pri := Med + 1;
if TCliente(OLst.Items[Med]).Nombre > Valor then Ult := Med - 1;
end;
if Esta then
Result := Med
else
Result := -1;
end;

// Ejemplo de llamada:
procedure TForm1.Button1Click(Sender: TObject);
var
P : Integer;
begin
P := BinarySearch(LstObj, 'Juan Perez');
if P <> -1 then
ShowMessage('Nombre: ' + TCliente(LstObj.Items[P]).Nombre+#10#13+
'Posición: ' + IntToStr(P));
// ...
end;

...

procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(LstObj) then
LstObj.Free;
end;


Saludos.

sebamawa
28-08-2012, 18:26:13
Muchas gracias ecfisa, algo como lo que planteaste tenía en mente y resulta de mucha ayuda.
Como he comentado, vengo de Pascal Estándar, o sea de arreglos estáticos, crear listas enlazadas desde cero, etc, y estoy tratando de migrar algunas estructuras de datos a Delphi como listas enlazadas y arboles, pero claro, Delphi ya tiene incorporadas muchas de estas estructuras o algunas semejantes que facilitan el tener que empezar a programar desde cero, supongo que esto se da en todo lenguaje moderno.
Me podrías decir donde encontrar descripciones de los métodos y propiedades de las clases de Delphi, es que a veces cuando tengo que realizar una tarea caigo en la duda si, es que tengo una rutina predefinida o no, y en este último caso debo implementar la misma por mi cuenta.
Otra duda, el método FindInstanceOf de la clase TObjectList, qué tarea realiza?
Y lo último, teniendo la posibilidad de realizar búsquedas binarias en una lista (TObjectList por ejemplo), sabiendo que este tipo de búsqueda es muy eficiente, tiene sentido el utilizar árboles para el guardado de datos?
Tal vez más de uno me dirá que use base de datos, pero antes quiero manejar con solvencia las estructuras de datos que menciono antes.

Muchas gracias.
Saludos para todos.

roman
28-08-2012, 19:10:37
Si la lista ya está ordenada podes usar una búsqueda binaria.

De hecho, modificando un poco, la misma función que se usa para la inserción se puede usar para la búsqueda. Es decir, se hace una sóla función de búsqueda que devuelva el índice donde debe ir el objeto. Ese índice se usa, bien sea para insertar un nuevo objeto, o bien para devolver la posición del objeto buscado.

// Saludos

ecfisa
28-08-2012, 19:25:26
Hola sebamawa.

Me podrías decir donde encontrar descripciones de los métodos y propiedades de las clases de Delphi
En la propia ayuda de Delphi encontras descrita las clases, sus propiedades y métodos. Sobre TList,TQueue,TStrings, etc revisa este (http://www.clubdelphi.com/foros/showpost.php?p=436201&postcount=3) enlace.

Otra duda, el método FindInstanceOf de la clase TObjectList, qué tarea realiza?
Busca la primera ocurrencia de una clase específica dentro de la lista. Si la clase buscada no existe devuelve el valor -1.

Saludos.

Delphius
28-08-2012, 22:36:55
tiene sentido el utilizar árboles para el guardado de datos?
Tal vez más de uno me dirá que use base de datos, pero antes quiero manejar con solvencia las estructuras de datos que menciono antes.

Muchas gracias.
Saludos para todos.
¿Árboles? Pasar de un TAD lista a un TAD árbol no es poca cosa. En primer lugar habría que determinar si efectivamente tiene sentido alguno (sobre todo en lo lógico) el almacenar datos en forma de árbol.
Desconozco si Delphi provee de fábrica un TObjectTreeList (por darle un nombre) pero me parece que el que consideres pensar en árboles, y que luego sobre este posiblemente se deba implementar y adaptar los algoritmos de insersión, ordenamiento y búsquda es ya algo exagerado y una pérdida de tiempo.

Lo mejor es que le dejes eso al motor de base de datos... que lo hace estupéndamente. Si ya de hecho los motores por dentro poseen árboles para estructurar los datos. Concretamente los B+ tree.

Luego es que existen tus clase del dominio, y crearás tantos objetos como registros tengas. Al extraer los registros pasas los datos a cada instancia en sus correspondientes campos. Y el paso inverso, desde tu clase del dominio lees sus campos y mandas a ejecutar una instrucción INSERT o UPDATE sea el caso.
A estas alturas y si quieres seguir avanzando de escala ya te vas pensando en un framework de persistencia.

Me parece que te estás complicando las cosas innecesariamente.

Saludos,

roman
28-08-2012, 22:56:47
¿Árboles? Pasar de un TAD lista a un TAD árbol no es poca cosa. En primer lugar habría que determinar si efectivamente tiene sentido alguno (sobre todo en lo lógico) el almacenar datos en forma de árbol.
Desconozco si Delphi provee de fábrica un TObjectTreeList (por darle un nombre) pero me parece que el que consideres pensar en árboles, y que luego sobre este posiblemente se deba implementar y adaptar los algoritmos de insersión, ordenamiento y búsquda es ya algo exagerado y una pérdida de tiempo.

Aquí ya me perdí. Mis cursos básicos de computación me dicen que los árboles binarios son excelentes candidatos para guardar información ordenada. Es más, yo diría que una lista ordenada con inserción y búsqueda como la que hemos expuesto es esencialmente lo mismo que un árbol binario.

// Saludos

Delphius
28-08-2012, 23:36:50
Aquí ya me perdí. Mis cursos básicos de computación me dicen que los árboles binarios son excelentes candidatos para guardar información ordenada. Es más, yo diría que una lista ordenada con inserción y búsqueda como la que hemos expuesto es esencialmente lo mismo que un árbol binario.

// Saludos
Pues si roman, pero hay árboles mejores que los binarios ;) Y B+ (http://en.wikipedia.org/wiki/B%2B_tree) está pensado justamente para equilibrar: inserción, lectura, navegación, ordenamiento, etc. Y ni que decir... más convenientes si luego se tiene pensado hacer lectura/escritura física en un archivo. Justamente estos son los que utilizan los motores de base de datos.

Sinceramente, pretender llegar a pensar en árboles es demasiado. Es mejor quedarse con la Lista, a como se ha propuesto... y que como bien dices, para este caso es equivalente al árbol binario. Si ya la lista con lo propuesto sirve ¿para que más?
Si en verdad se quiere llevar al TAD árbol, y que se comporte como tal, pues habrá que buscar una clase, si es que ya está. O bien volver a retormar las clases de estructuras de datos.

A mi parecer, creo que se está perdiendo la sintonía del problema y buscar resolverlo de una forma más complicada de la que se podría llevar. Y lo digo precisamente porque algo me dice que sebamawa ha perdido de vista algo, porque algo le hace pensar ahora que árboles le resultará más adecuado.

¿No será mejor invitar a que se descubra y explique ese algo? Yo creo que de algo nos estamos perdiendo.

Saludos,

sebamawa
29-08-2012, 01:44:56
Estimados amigos, primero que nada les agradezco sus sugerencias y ayuda.
Estoy de acuerdo con lo que dice Delphius, estoy complicando las cosas, y seguramente eso se de porque aún me falta aprender muchas herramientas de Delphi.
Lo he dicho más de una vez, mi base previa en programación es Pascal Estándar, un curso con FreePascal y otro con Modula2 (que básicamente es Pascal para trabajar de forma modular).
Con los compiladores anteriores sólo trabajabamos con la consola Dos, o sea, todas las salidas se realizaban de modo texto en la consolita. Los cursos que mencioné estaban enfocados a adquirir los rudimentos de la programación estructurada (con FreePascal) y la programación modular (Modula2).
Prácticamente todo lo hacíamos desde cero, listas enlazadas, árboles, arreglos con tope, etc; claro que no eran superaplicaciones ni mucho menos lo que realizabamos partiendo "desde la nada".
Pero de interfaces gráficas, nada de nada, es por ello que yo de forma autodidacta he querido sumergirme un poco en la programación con interfaces de este tipo, y para ello elegí Delphi, pues es una forma de seguir conectado con Pascal.
Pero, está recontra claro, que la potencialidad y las herramientas de Delphi te ahorran mucho trabajo, y es por ello que a veces sin quererlo complico un poco las cosas queriendo traer algunas estructuras de Pascal Estándar que ya están predefinidas en Delphi como TAD's.

Nuevamente gracias, y espero se entienda en parte por qué he planteado ciertas dudas.
Saludos.

roman
29-08-2012, 18:16:17
Pues si roman, pero hay árboles mejores que los binarios ;) Y B+ (http://en.wikipedia.org/wiki/B%2B_tree) está pensado justamente para equilibrar: inserción, lectura, navegación, ordenamiento, etc. Y ni que decir... más convenientes si luego se tiene pensado hacer lectura/escritura física en un archivo. Justamente estos son los que utilizan los motores de base de datos.

Sinceramente, pretender llegar a pensar en árboles es demasiado. Es mejor quedarse con la Lista, a como se ha propuesto... y que como bien dices, para este caso es equivalente al árbol binario. Si ya la lista con lo propuesto sirve ¿para que más?
Si en verdad se quiere llevar al TAD árbol, y que se comporte como tal, pues habrá que buscar una clase, si es que ya está. O bien volver a retormar las clases de estructuras de datos.

A mi parecer, creo que se está perdiendo la sintonía del problema y buscar resolverlo de una forma más complicada de la que se podría llevar. Y lo digo precisamente porque algo me dice que sebamawa ha perdido de vista algo, porque algo le hace pensar ahora que árboles le resultará más adecuado.

¿No será mejor invitar a que se descubra y explique ese algo? Yo creo que de algo nos estamos perdiendo.

Saludos,

Sinceramente creo que rizas demasiado el rizo. No he visto que el forista haya pretendido hacer una motor de base de datos ni nada por el estilo. Más bien veo alguien que trata de familiarizarse con delphi implmentando algunas de las estructuras clásicas de datos. Pero una frase como

En primer lugar habría que determinar si efectivamente tiene sentido alguno (sobre todo en lo lógico) el almacenar datos en forma de árbol.

lejos de enriquecer la plática, oscurece el asunto. Si no almacenas datos en un árbol, ¿qué coños almacenas ahí? Desde luego que hay mejores o peores tipos de datos para cada tarea y que muy posiblemente cuando se ponga a la tarea real que le ocupe, pensará en una base de datos, pero considero que hay que tomar los hilos y las respuestas en su justa medida y no hacer una cátedra teórica en cada caso.

// Saludos

Delphius
29-08-2012, 21:08:33
Sinceramente creo que rizas demasiado el rizo. No he visto que el forista haya pretendido hacer una motor de base de datos ni nada por el estilo. Más bien veo alguien que trata de familiarizarse con delphi implmentando algunas de las estructuras clásicas de datos.

Yo no digo que pretenda hacer una base de datos, sino más bien tratar de entender el trasfondo de todo esto.
Por más que esto se trate de alguna práctica, debe haber algún objetivo detrás de esto, y que va más allá de practicar con los TADs.
Si en verdad lo que se busca es practicar con TADs pues entonces lo más apropiado es justamente utilizar TQueue, TStack, TList, para Colas, Pilas, Listas, algún derivado o similar de la familia de los TTreeView para árboles y se opere con estos. Es decir, tomar aquellos prácticos que se nos daban en la cátedra de estructuras de datos.

Y si en verdad se quiere llegar a implementar su propia clase, pues con más razón: agarrar los libros de estructuras de datos, repasar el tema de punteros e implementar los algoritmos. Justo casi igual que en la vieja escuela. Pero he aquí que las dudas me parecen encaminar a algo más profundo que eso y no es una cosa de una simple práctica de TADs sino que se intenta responder y utilizar a los TADs para algo que busca a hacer.
Parte de ese algo nos ha comentado, pero me parece que hay un iceberg oculto y no logramos ver. Y lo digo en buen plan, porque si ya se ha propuesto algunas soluciones y que ahora resulta que quiere ir a por árboles, es el momento de decir: Momento... ¿a donde más quieres llegar? Mejor analicemos el problema de otra forma, cual es el contexto a analiza y de allí vemos las posibles sugerencias y te damos los elementos para que practiques.


Pero una frase como
(...)
lejos de enriquecer la plática, oscurece el asunto.

No roman, no la oscurece.... Más bien intento traer luz, hay algo más allá de una simple práctica. Partamos de algo: cuales son los conocimientos que el interesado tiene, cual es el contexto que analiza, y vemos el mejor modo de guiar.
Porque así lo que se dará serán contenidos sueltos, uno después del otro y no necesariamente con alguna corelación cuando en realidad lo que más les favorece a los que se inicia es tener un buen plan de práctica que le ofrezca un paneo general y con un temario que sea escalado y sepa unir a los conceptos.
Si respondemos hoy sobre TObjectList, mañana sobre árboles, y quien sabe si luego en un mes es sobre grafos y vemos que se sigue dando vueltas en el mismo problema es una clara y evidente señal de que algo no se ha comprendido bien.


Si no almacenas datos en un árbol, ¿qué coños almacenas ahí? Desde luego que hay mejores o peores tipos de datos para cada tarea y que muy posiblemente cuando se ponga a la tarea real que le ocupe, pensará en una base de datos, pero considero que hay que tomar los hilos y las respuestas en su justa medida y no hacer una cátedra teórica en cada caso.
// Saludos
A ver roman, yo no dije que en un árbol no se ha almacenar datos. Sino más bien que quizá en términos lógicos AL PROBLEMA no sea lo más apropiado si hay una manera más simple de encararlo. Tu entendiste al término lógico, como algo interno al árbol. Me refería que quizá no hace demasiado a la lógica del problema.

Si los datos y las posibles operaciones a esperarse no dan ciertas evidencias de comportarse con dicha estructura es quizá el momento de preguntarse si el utilizar formal y explícitamente un árbol le aporta más valor... ¡a una mente que ya está confundida!

No pretendo dar una cátedra teórica en cada post, sino más bien evidenciar de que el problema se lo está planteando algo exagerado. Precisamente demuestro con exageraciones el impacto y a donde se lo está por intentar llevar al hilo.

Repito y sostengo: antes de empezar a saltar al tema de los árboles, ¿Será realmente necesario? ¿Porqué no discutir los verdaderos y demás objetivos tras todo esto?
Realmente te me sulfuraste conmigo al divino botón. :mad:

Saludos,

roman
29-08-2012, 21:15:49
Está bien Delphius, tranquilo, no te vayas a provocar una úlcera.

// Saludos