IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Insertion rapide dans une liste chainée


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Insertion rapide dans une liste chainée
    Bonjour,

    Pour mon stage je dois réaliser un code utilisant une liste chainée. Je met en œuvre et j'utilise cette liste sans problème.

    Le seul inconvénient est que lorsque j’insère un élément (identifié par un ID), je dois le placer correctement dans la liste.

    La liste globale représente environs 30 millions d'éléments (oui c'est gros mais c'est comme ça ...) et les éléments sont insérés les un après les autres quand ils arrivent (je lis un fichier txt).

    Du coup si j’insère un élément en faisant une comparaison bête et méchante des éléments un à un en parcourant la liste cela est très très très long évidement ...

    Je viens donc ici pour avoir votre avis sur comment optimiser l'insertion d'un nouvel élément dans cette liste chainée mais surtout si si vous avez du code à partager je suis preneur ...

    Cordialement,

    PlayBoy31

  2. #2
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour

    je dois le placer correctement dans la liste
    correctement, oui, certes, mais tu entends quoi par là ? Les éléments de ton fichier texte sont "en vrac" (dans un ordre quelconque) et tu construis ta liste en la maintenant ordonnée (relation d'ordre sur les ID des éléments) ? C'est le plus probable et je pars là dessus mais ce serait bien que tu confirmes (ou pas).

    Déjà, il existe des gestionnaires de listes qui proposent des "insertions triées" d"éléments comme, par exemple, dans GLib, avec les GList et la fonction g-list-insert-sorted. Après, je ne sais pas ce qu'elle vaut niveau performances et si ça peut résoudre ton problème.

    Sinon, si tu n'as pas le choix des listes (des types) à utiliser, il faut que tu réduises le nombre de comparaisons à faire à chaque insertion d'un nouvel élément.

    Utilise plusieurs listes : un tableau ordonné de listes ordonnées ou même une liste ordonnée de listes ordonnées). A chaque insertion, tu détermines d'abord dans quelle liste tu vas insérer ton nouvel élément (tu parcours ton taleau (ou ta liste) de listes), ensuite tu appliques ce que tu fais actuellement mais sur une liste avec moins d'éléments.

    Après le choix entre le tableau ou la liste de listes dépend beaucoup de ton contexte et si tu as une petite idée de la plage des ID présents dans ton fichier initial : est-ce que tu peux prévoir, initialement, des paquets de tailles à peu près homogènes ou pas.

    Tu peux aussi envisager d'avoir un découpage à plusieurs niveaux : 30 millions = 1 x 30 000 000 (ce que tu fais) = 1 000 x 30 000 (2 niveaux) = 100 x 100 x 3000 (3 niveaux) = etc...

    Une fois ton fichier complétement traité, tu concatènes les listes d'éléments pour obtenir LA liste résultat (la concaténation des listes, ce n'est pas bien méchant : tout le boulot se fait aux extrémités et dépend du nombre de listes, pas des éléments - pour les GList, c'est proposé)

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pas besoin de faire plusieurs listes, une seule suffit mais avec plusieurs pointeurs.

    Ainsi plus besoin de concaténer les petites listes pour obtenir une liste final.

    Tu peux aussi regarder le premier caractère et en fonction choisir le pointeur approprié.
    Par contre il ne faudra pas pointeur sur l'élément de début de sous-liste souhaité mais sur celui d'avant pour les insertions.

    Exemple : sous-liste a contient les mot commençant par a
    sous-liste aa ceux commençant par aa
    sous-liste ab ...
    etc...

  4. #4
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Citation Envoyé par Neckara
    Pas besoin de faire plusieurs listes, une seule suffit mais avec plusieurs pointeurs.
    Oui, tout à fait, tu as parfaitement raison.

    A la lecture (peut-être trop rapide), j'avais compris que le "type" liste lui était fourni, avec les fonctions "qui vont bien" mais qu'il ne "maitrisait" pas le source et/ou l'implémentation. Et dans ce cas, des pointeurs pour pointer sur quoi ?

    En passant par des sous-listes, ça permettait de rester simple utilisateur de la lib, sans avoir à connaître/utiliser l'implémentation. Tout dépend du contexte qu'il a peu détaillé.

    Sinon, attention aux fameux ID : tu pars sur des caractères. Les entrées sont dans un fichier texte, certes. Mais les ID sont peut être autre chose que des chaines. Faudrait qu'on en sache un peu plus.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pour choisir le pointeur de sous-liste, je pense avoir une méthode très rapide avec des tableau de pointeurs pour le 3ème octet.
    Un tableau de pointeur de pointeur pour le 2ème et un tableau de pointeur de pointeur de pointeur pour le premier ce qui donne :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    pointeur = tableau[*((char *)&identifiant+taille)][*((char *)&identifiant+taille - 1)][*((char *)&identifiant+taille - 2)];
    Si l'identifiant est un char * , on enlève le '&'

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Tout cela revient à faire une table de hashage contenant des pointeurs vers des éléments de la liste. La question en suspend est de bien choisir la fonction de hashage selon le critère de placement (la nature de ID) dans la liste.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonsoir et merci pour vos réponses!

    Tout d'abord point que je n'ai pas mentionné désolé, le code doit être portable sous linux et windows, du coup c'est dommage pour les Glist ...

    En fait, les ID représentent une donnée temps en secondes. Les données ne sont pas dans l'ordre dans le fichier txt et je parcours le fichier pour récupérer la donnée temps et d'autres champs que je modifie correspondant à cette donnée temps avant de l'insérer dans la liste.

    j'avoue être un peu perdu avec les solutions évoqué comme pointeur de sous liste et table de hashage ...

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    par exemple :

    si un elément de ta liste est :

    typedef struct ELT ...

    tu peux très bien stocker au fur et à mesure l'adresse de l'élement démarrant une lettre de l'alphabet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct ELT *list_elt, elt, *tab[26] ;
     
    elt = ajoute_elt ( &list_elt);
    if ( elt->champ[0] == 'a' )
       tab[0] = elt ;
    ...
    et ensuite tu ne parcours que tab (donc 26) pour trouver entre quel et quel élément tu dois hercher à insérer..

    Tu peux le faire aussi en temps :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ( elt->heure == (lastheure+1) )
       tab[lastheure+1] = elt ;
    etc etc.. suivant ton meilleur critère..

Discussions similaires

  1. Insertion dans une liste chainée
    Par liraquikhalil dans le forum C
    Réponses: 3
    Dernier message: 24/09/2014, 12h40
  2. Réponses: 2
    Dernier message: 05/01/2014, 01h07
  3. Réponses: 7
    Dernier message: 21/11/2012, 12h40
  4. Réponses: 2
    Dernier message: 21/05/2012, 07h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo