BotonMenu
BotonIndice

Visita : conoce3000.com
Paypal : https://www.paypal.com/donate/?hosted_button_id=XY8TZ3MGN64GE

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL


13. LISTAS Y COLECCIONES.
13.8. ORDENANDO LISTAS Y COLECCIONES.
13. LISTAS Y COLECCIONES.
13.8. ORDENANDO LISTAS Y COLECCIONES.
13. LISTAS Y COLECCIONES.
13.8. ORDENANDO LISTAS Y COLECCIONES.

SIGUIENTE

SIGUIENTE

SIGUIENTE


‒ Ordenando listas y colecciones.

Tanto las listas como las colecciones tienen un método para ordenar sus elementos, el método se conoce como Sort, de ordenar en ingles este usa el algoritmo de ordenamiento rápido (Quick Sort), pero con la diferencia que este método necesita que se le suministre una función para comparar los elementos de la lista.

En el caso de la lista la función debe ser como lo indica el del puntero a función TListSortCompare que es declarado internamente como sigue:

type TListSortCompare = function(Item1: Pointer;Item2: Pointer):Integer;

y para las colecciones el puntero a función es TcollectionSortCompare, y es declarado como sigue:

type TCollectionSortCompare = function(Item1: TCollectionItem;Item2: TCollectionItem):Integer;

La función de comparación que se debe crear para ordenar los elementos de una lista, debe devolver uno de los siguientes valores. Devolverá 0 cuando sean iguales, devolverá negativo cuando el primer elemento a comparar es menor que el segundo, y devolverá positivo en caso contrario. Es decir si devuelve un valor cero el método sort no hará ningún intercambio, si devuelve un número positivo ordena la parte superior o izquierda de la lista, si es negativo ordenara la parte inferior o derecha de la lista y así sucesivamente. Por defecto el método sort ordena los elementos siempre en orden ascendente. A continuación un ejemplo que ordena una lista de enteros en orden ascendente.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils,classes;

function Compara(i,j:pointer):integer;
Begin
  if integer(i^)=integer(j^) then Compara:=0
  else if integer(i^) > integer(j^) then Compara:=1
  else Compara:=-1
End;

Var
 Lista:TList;
 n01:^integer;
 i:integer;
 aux:pointer;

Begin
  Randomize;
  Lista:=TList.create;
  for i:=0 to 10 do
   Begin
    new(n01);
    n01^:=random(200);
    Lista.add(n01)
   End;
  Writeln('DESORDENADO');
  for aux in Lista do Writeln(integer(aux^):3);

  Lista.Sort(@Compara);

  Writeln('ORDENADO');
  for aux in Lista do Writeln(integer(aux^):3)
End.
Código fuente 26: Ordenando una lista.
Descargar

El programa ordena en orden ascendente todos los números de nuestra lista, en caso deseamos ordenarlo en orden descendente tendremos que simplemente cambiar el orden en que se comparan los elementos a ordenar, podemos hacerlo con otra función de comparación que ejecuta la anterior pero con los elementos a comparar intercambiados. En el siguiente ejemplo se implementa una lista con objetos que contienen un número entero, en estos casos hay que tener cuidado con el solapamiento, y este se debe hacer siempre con la clase padre de todos los objetos que contiene la lista.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils,classes;

Type
  TEntero=class
    n:integer;
    Constructor create(p:integer);
    Procedure Mostrar;
  End;

  Constructor TEntero.create(p:integer);
   Begin
     n:=p
   End;

  Procedure TEntero.Mostrar;
   Begin
     Writeln(n:3)
   End;

 function ComparaAsc(i,j:pointer):integer;
  Begin
    if TEntero(i).n = TEntero(j).n then ComparaAsc:=0
    else if TEntero(i).n > TEntero(j).n then ComparaAsc:=1
    else ComparaAsc:=-1
  End;

  Function ComparaDesc(i,j:pointer):integer;
   Begin
     ComparaDesc:=ComparaAsc(j,i)
   End;

Var
 Lista:Tlist;
 i:integer;
 aux:pointer;
Begin
  Randomize;
  Lista:=Tlist.create;
  for i:=0 to 10 do
    Lista.add(TEntero.create(random(200)));

  Writeln('DESORDENADO');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaAsc);

  Writeln('ORDENADO Ascendente');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaDesc);

  Writeln('ORDENADO Descendente');
  for aux in Lista do TEntero(aux).Mostrar;
End.
Código fuente 27: Ordenando una lista en orden ascendente y descendente.
Descargar

En este ejemplo los nombres de las funciones de comparación son ComparaAsc y ComparaDesc, la segundo es la función que simplemente llama a ComparaAsc con los elementos intercambiados. En los ejemplos anteriores estamos ordenando listas que sólo contienen valores numéricos, en estos casos se puede evitar los if anidados que se usan con las funciones de comparación haciendo una simple resta. Con esta resta podemos obtener un 0, si ambos son iguales, si el primer elemento a comparar es mayor que el segundo obtendremos un número positivo y en caso contrario un número negativo. A continuación el ejemplo anterior usando una resta.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils,classes;

Type
  TEntero=class
    n:integer;
    Constructor create(p:integer);
    Procedure Mostrar;
  End;

  Constructor TEntero.create(p:integer);
   Begin
     n:=p
   End;

  Procedure TEntero.Mostrar;
   Begin
     Writeln(n:3)
   End;

 function ComparaAsc(i,j:pointer):integer;
  Begin
    ComparaAsc:=TEntero(i).n-TEntero(j).n
  End;

  Function ComparaDesc(i,j:pointer):integer;
   Begin
     ComparaDesc:=ComparaAsc(j,i)
   End;

Var
 Lista:Tlist;
 i:integer;
 aux:pointer;
Begin
  Randomize;
  Lista:=Tlist.create;
  for i:=0 to 10 do
    Lista.add(TEntero.create(random(200)));

  Writeln('DESORDENADO');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaAsc);

  Writeln('ORDENADO Ascendente');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaDesc);

  Writeln('ORDENADO Descendente');
  for aux in Lista do TEntero(aux).Mostrar;
End.
Código fuente 28: Ordenando una lista de enteros con una resta.
Descargar

El siguiente ejemplo es como implementar en este caso el mismo ejemplo anterior pero usando colecciones.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils,classes;

Type
  TEntero=class(TCollectionitem)
   public
    n:integer;
    Procedure Mostrar;
  End;

  Procedure TEntero.Mostrar;
   Begin
     Writeln(n:3)
   End;

 function ComparaAsc(i,j:TCollectionitem):integer;
  Begin
    ComparaAsc:=TEntero(i).n-TEntero(j).n
  End;

  Function ComparaDesc(i,j:TCollectionitem):integer;
   Begin
     ComparaDesc:=ComparaAsc(TEntero(j),TEntero(i))
   End;

Var
 Lista:TCollection;
 i:integer;
 aux:pointer;
 n01:TEntero;
Begin
  Randomize;
  Lista:=TCollection.create(TEntero);
  for i:=0 to 10 do Begin
    n01:=TEntero(Lista.add);
    n01.n:=random(200)
  End;

  Writeln('DESORDENADO');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaAsc);

  Writeln('ORDENADO Ascendente');
  for aux in Lista do TEntero(aux).Mostrar;

  Lista.Sort(@ComparaDesc);

  Writeln('ORDENADO Descendente');
  for aux in Lista do TEntero(aux).Mostrar;
End.
Código fuente 30: Ordenando una colección en orden ascendente y descendente.
Descargar

En caso de una colección en donde los elementos son heterogéneos es decir se debe tener presente que el solapamiento que se usa en la función de comparación, se haga con la clase padre de los objetos de la colección, en la mayoría de los casos es lo recomendado. El siguiente ejemplo ordena una lista de personas que pueden ser estudiantes o cualquier otra persona.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils,classes;

Type

   TPersona=class(TCollectionItem)
     public
      Nombre:ansistring;
      procedure Mostrar;virtual;
   End;

   TEstudiante=class(TPersona)
     public
      grado:byte;
     procedure Mostrar;override;
   End;

   Procedure TPersona.Mostrar;
     Begin
      Writeln(Nombre);
     End;

   procedure TEstudiante.Mostrar;
     Begin
       Writeln(Nombre,', grado:',grado);
     End;

  function ComparaAsc(i,j:TCollectionitem):integer;
   Begin
    if TPersona(i).Nombre=TPersona(j).Nombre then ComparaAsc:=0
    else if TPersona(i).Nombre>TPersona(j).Nombre then ComparaAsc:=1
    else ComparaAsc:=-1
  End;

  Function ComparaDesc(i,j:TCollectionitem):integer;
   Begin
     ComparaDesc:=ComparaAsc(TPersona(j),TPersona(i))
   End;


Var Personas:TCollection;
    aux:TPersona;
Begin
  Personas:=TCollection.create(TPersona);

  Personas.Add;
  TPersona(Personas.items[0]).Nombre:='Carlos';

  aux:=TEstudiante.create(Personas);
  TEstudiante(aux).Nombre:='Jose';
  TEstudiante(aux).grado:=2;

  Personas.Add;
  TPersona(Personas.items[2]).Nombre:='Maria';

  aux:=TEstudiante.create(Personas);
  TEstudiante(aux).Nombre:='Ana';
  TEstudiante(aux).grado:=2;

   Writeln('ORDENADO Ascendente');
   Personas.Sort(@ComparaAsc);
   for TCollectionItem(aux) in Personas do aux.Mostrar;

   Writeln('ORDENADO Descendente');
   Personas.Sort(@ComparaDesc);
   for TCollectionItem(aux) in Personas do aux.Mostrar

End.
Código fuente 31: Ordenando una colección heterogenea.
Descargar




SIGUIENTE
SIGUIENTE
SIGUIENTE


 
‒ Comentarios y sugerencias.

Agradezco de antemano, todo comentario, sugerencia, y donativo a través de , que ayude a mejorar los contenidos educativos de Conoce 3000. Además, cualquier pregunta o duda que tengas lo puedes hacer por este medio. Pero, todo contenido que pueda resultar ofensivo, malicioso, racista, sexista, discriminatorio, obsceno, vulgar será eliminado. Para clases particulares contactame por whatsapp al 📲 (+51) 999 264 073








PORTADA |  INTERESANTE |  APUNTES |  LIBROS |  GALERIA


Creative Commons License


Todos los textos, imágenes y videos de Conoce3000 estan colocados bajo una licencia : Creative Commons Reconocimiento-NoComercial 3.0 Unported License.