2012-01-08 3 views
1

Pour Delphi (2009 ou plus récent), est-il une mise en œuvre d'une liste d'objets avec ces deux caractéristiques:liste d'objets triables avec O (1) suppression du premier élément

  • permet de trier sur mesure

  • effectue des suppressions du premier élément de la liste en O (1) temps

+0

J'ai jeté un rapide coup d'œil à la source (Delphi 7) et l'implémentation était définitivement O (n) pour enlever le premier élément. Cela étant dit, ce ne serait pas si difficile à écrire si vous venez de développer TAbstractList en utilisant une implémentation de liste de base. Honnêtement je ne sais pas pourquoi ce n'est pas O (n) hors de la boîte ... bonne chance. –

+0

Voici une [bibliothèque de collections génériques delphi] (http://code.google.com/p/delphi-coll/wiki/CollectionDetails) avec TObjectLinkedList, qui gère le tri. TPriorityQueue existe également, mais vous devrez implémenter le tri vous-même. –

Répondre

4

Il n'y a rien qui est livré avec le produit qui a ces propriétés. La solution évidente et simple est d'inverser l'indexation de la liste de sorte que lorsque vous supprimez le premier élément, le code efface réellement le dernier élément de la liste sous-jacente.

Pour vous donner une idée de ce que je veux dire, voici l'esquisse des débuts d'une implémentation très basique. Il faudrait beaucoup de travail à mener à terme.

type 
    TMyObjectList<T> = class 
    private 
    FList: TObjectList<T>; 
    function GetItem(Index: Integer): T; 
    function ReversedIndex(Index: Integer): Integer; 
    public 
    constructor Create; 
    destructor Destroy; override; 
    property Items[Index: Integer]: T read GetItem; default; 
    procedure Delete(Index: Integer); 
    end; 

function TMyObjectList<T>.Create; 
begin 
    inherited; 
    FList := TObjectList<T>.Create; 
end; 

destructor TMyObjectList<T>.Destroy; 
begin 
    FList.Free;//don't use FreeAndNil because it offends Nick Hodges ;-) 
    inherited; 
end; 

function TMyObjectList<T>.ReversedIndex(Index: Integer): Integer; 
begin 
    Result := Count-1-Index; 
end; 

function TMyObjectList<T>.GetItem(Index: Integer): T; 
begin 
    Result := FList[ReversedIndex(Index)]; 
end; 

procedure TMyObjectList<T>.Delete(Index: Integer); 
begin 
    FList.Delete(ReversedIndex(Index)); 
end; 

Je suppose que vous voulez un tableau que votre stockage sous-jacent parce que je suppose que vous voulez O (1) accès aléatoire.

Toutes les autres fonctions dont vous avez besoin, qui utilisent un paramètre d'index, doivent également appeler ReversedIndex. La chose la plus difficile à écrire serait les routines de tri. Les classes dans Generics.Collections utilisent IComparer<T>. Vous feriez la même chose, mais délégueriez le tri à FList en passant un comparateur local IComparer<T> qui a annulé les résultats du comparateur fourni par l'appelant.

+1

+ 1 pour m'avoir montré que j'aurais pu le résoudre simplement par une utilisation à l'envers d'une liste régulière, en supprimant à la fin au lieu du début de la liste. Mais ensuite j'ai réalisé que j'avais fait une troisième hypothèse - que l'ajout à la fin doit se produire dans O (1) aussi. Mais alors je ne peux pas utiliser cette solution intelligente, mais j'ai besoin d'une sorte de liste double-liée. – mjn

+0

Maintenant vous changez les règles du jeu! O (1) les deux extrémités et le tri rapide est difficile. Le tri des listes liées n'est pas facile. Voulez-vous un accès aléatoire pour être rapide? –

+0

Une file d'attente de priorité similaire à celle-ci (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/PriorityQueue.html) à l'esprit. En fait, ma cible bouge rapidement, l'ajout à une file d'attente ordonnée ne se produit pas à la fin mais de nouveaux éléments seront insérés en fonction de l'ordre de tri :) (il fait partie d'une solution de cache d'objets) – mjn

Questions connexes