begin process at 2012 05 30 07:43:31
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

QuickSort : liste chaînée


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

QuickSort : liste chaînée

lundi 6 juin 2005 à 17:14:48 | QuickSort : liste chaînée

vegeta07

Salut,

Je souhaite réaliser le tri QuickSort (récursif) sur une liste simplement chaînée.
Mais j'ai un probleme sur la recursivité je pense.

Si quelqu'un a le temps de regarder le code (peu compliqué), j'aimerais avoir votre avis ou au mieux votre solution.

Merci.


lundi 6 juin 2005 à 17:19:09 | QuickSort : liste chaînée

vegeta07

Salut,

Je souhaite réaliser le tri QuickSort (récursif) sur une liste simplement chaînée.
Mais j'ai un probleme sur la recursivité je pense.

Si quelqu'un a le temps de regarder le code (peu compliqué), j'aimerais avoir votre avis ou au mieux votre solution.

Merci.

avec le code c 'est mieux.

#include <stdio.h>
#include <stdlib.h>


typedef struct noeud
{
    int valeur;
    struct noeud *suivant;
} element;
 
typedef element *liste;


int vide(liste lc)
{
    return (lc==NULL);
}
/* retourne un pointeur sur le dernier element de la liste */
liste pointeur_fin(liste lc)
{
liste tmp;
tmp=(liste)malloc(sizeof(element));
tmp=lc;
    if(!vide(lc) && !vide(lc->suivant))
    {
       while((tmp->suivant)!=NULL)
       {
            tmp=tmp->suivant;
       }
       return tmp;
    }
return tmp;
}

liste ajoutFIN(liste l, int val)
{
    liste tmp,nouv;
    tmp=l;
    nouv=(liste)malloc(sizeof(element));
    nouv->suivant=NULL;
    nouv->valeur=val;
    if(l==NULL)
    {
        l=nouv;
    }
    else
    {
        while(!vide(tmp->suivant))
        {
            tmp=tmp->suivant;
        }
        tmp->suivant=nouv;
    }
return l;
}

liste creation(liste lc)
{
   
    int nbval,val,i=0;
    printf("\nEntrez le nombre de valeur a saisir : ");
    scanf("%d",&nbval);   
    while(i<nbval)
    {
        printf("\nEntrez la valeur %d : ",i+1);
        scanf("%d",&val);
        lc=ajoutFIN(lc,val);
        i++;
    }
return lc;
}

void afficher(liste lc)
{
printf("\n\nListe chainee obtenue : \n\n");
    while(!vide(lc))
    {
        printf("%3d",lc->valeur);
        lc=lc->suivant;
    }
}
/* fonction permettant d'acceder au precedent d'un element */
liste precedent(liste lc, int val)
{
    liste tmp,tmp1;
    tmp=lc;
    tmp1=tmp->suivant;
    while((tmp1->valeur)!=val)
    {
        tmp1=tmp1->suivant;
        tmp=tmp->suivant;
    }
return tmp;
}

/* fonction permettant de partitionner la liste :
les valeurs superieur au pivot sont a doite et inversement*/

liste partition (liste lc,liste debut, liste fin)
{
    int permu;
    int pivot=debut->valeur;
    liste compt=debut;
    liste tmp=debut->suivant;
    if(!vide(debut))
    {   
        while((tmp)!=(fin->suivant))
        {
            if((tmp->valeur)<pivot)
            {
                compt=compt->suivant;
                permu=tmp->valeur;
                tmp->valeur=compt->valeur;
                compt->valeur=permu;
            }
            tmp=tmp->suivant;
        }   
        permu=debut->valeur;
        debut->valeur=compt->valeur;
        compt->valeur=permu;
        return compt;         
    }
}

/* Fonction supposée réaliser le tri ... */
void quicksort(liste lc, liste debut, liste fin)
{
    if((debut->valeur)<(fin->valeur))
    {
        liste pivot=partition(lc,debut,fin);         
        quicksort(lc,debut,precedent(lc,pivot->valeur));
        quicksort(lc,(pivot->suivant),fin);
    }
}

int main(void)
{
liste lc=NULL;
liste debut=NULL;
liste fin=NULL;

lc=creation(lc);
afficher(lc);

debut=lc;
fin=pointeur_fin(lc);

quicksort(lc,debut,fin);
afficher(lc);

  return 0;
}

lundi 6 juin 2005 à 17:28:29 | Re : QuickSort : liste chaînée

darfeuille

j'ai pas le temps de tout verifier, mais je vois que tu fais

   int pivot=debut->valeur;
    liste compt=debut;
    liste tmp=debut->suivant;
    if(!vide(debut))

  si debut == Null (ce que tu teste apres par if(!vide(debut)) justement)
   pivot = debut->valeur va te faire des erreurs



Change ca, ca marchera peut etre apres, sinon rien ne me saute aux yeux.
lundi 6 juin 2005 à 17:47:18 | Re : QuickSort : liste chaînée

vegeta07


Merci pour la remarque, tu as tout à fait raison.

Mais je crois surtout que c'est ma condition d'arret qui est mauvaise.

Avec ta modif, j'ai ensuite essayé de changer cette condition en comparant les positions des pointeurs "debut" et "fin"  (comme si c'était un tableau).
Et le prog ne fonctionne toujours pas... malédiction


/* donne le rand d'un element comme dans un tableau*/
int compteur(liste lc, liste elem)
{
    liste tmp=lc;
    int cpt=0;
    if (!vide(lc))
    {
        while(!vide(tmp) && (tmp->valeur)!=(elem->valeur))
        {
            cpt++;
            tmp=tmp->suivant;
        }
    return cpt;
    }
   
}

/* Fonction supposée réaliser le tri ... */
void quicksort(liste lc, liste debut, liste fin)
{

    liste pivot=partition(lc,debut,fin);

/* modification de la condition*/ 

 if((compteur(lc,debut))<(compteur(lc,fin)))
    {          
       
        quicksort(lc,debut,precedent(lc,pivot->valeur));
        quicksort(lc,(pivot->suivant),fin);
    }
}

mardi 7 juin 2005 à 00:04:07 | Re : QuickSort : liste chaînée

vdust

Pas besoin d'allourdir ton code avec ta fonction compteur. Juste quelques modifications, en paufinant le contrôle de la terminaison de l'algorithme :

liste partition (liste lc, liste debut, liste fin)
{
    int permu;
    int pivot; //=debut->valeur; // on le définira plus tard
    liste compt = debut; // ici, on laisse. Si NULL pas grave
    liste tmp; //=debut->suivant; // et re ^^
    if(!vide(debut))
    {   
        //on initialise tout maintenant qu'on peut
        //de manière sûre
        pivot = debut->valeur;
        compt = debut
        tmp   = debut->suivant;
        while((tmp)!=(fin->suivant))
        {
            if((tmp->valeur)<pivot)
            {
                compt=compt->suivant;
                permu=tmp->valeur;
                tmp->valeur=compt->valeur;
                compt->valeur=permu;
            }
            tmp=tmp->suivant;
        }   
        permu=debut->valeur;
        debut->valeur=compt->valeur;
        compt->valeur=permu;
//        return compt; // ne traite que le cas ou 'debut' non null
    }
    return compt; // retourne un élément lorsque 'debut' est non null, NULL sinon.
}

/* Fonction supposée réaliser le tri ... */
void quicksort(liste lc, liste debut, liste fin)
{
    if((debut->valeur)<(fin->valeur))
    {
        liste pivot=partition(lc,debut,fin);
        if(!vide(pivot)){ // si pivot vide, rien à faire
                          // c'est la terminaison attendue

            quicksort(lc,debut,precedent(lc,pivot->valeur));
            quicksort(lc,(pivot->suivant),fin);
        }
    }
}

Bien qu'en apparence, cet algorithme pour les listes chaînées simples ressemble à un Quicksort, elle n'en est pas moins très éloignée en terme de complexité (temps d'execution), en raison de la fonction 'precedent' qui nécessite à chaque fois de reparcourir la liste depuis le début, ce qui est catastrophique dans le cas de très grandes listes. Je ne sais pas si tu as l'intention de l'utiliser dans un programme quelconque, mais je ne t'y encouragerais absolument pas. Mieux vaut dans ce cas utiliser une liste doublement chaînée qui donne de bien meilleurs résultats (l'élément précédent est obtenu instantanément par exemple).

J'espère cependant que l'algorithme fonctionne maintenant (je n'ai vérifié que sur le papier ^^)

++

-- Virtual Dust --
mardi 7 juin 2005 à 00:17:44 | Re : QuickSort : liste chaînée

vdust

Petite erreur dans mon précédent message, dans la fonction quicksort. Sur la condition if(!vide(pivot))... j'ai oublié un cas

void quicksort(liste lc, liste debut, liste fin)
{
    if((debut->valeur)<(fin->valeur))
    {
        liste pivot=partition(lc,debut,fin);
        if(!vide(pivot)){ // si pivot vide, rien à faire
                          // c'est la terminaison attendue

            quicksort(lc,debut,precedent(lc,pivot->valeur));
            if(!vide(pivot->suivant))
                quicksort(lc,(pivot->suivant),fin);
        }
    }
}


-- Virtual Dust --



Cette discussion est classée dans : liste, chaînée, quicksort


Répondre à ce message

Sujets en rapport avec ce message

Liste chaînée, besoin d'aide! [ par mystik007 ] Bonjour, je dois coder un programme qui manipule les listes chaînées, j'aurais besoin d'aide pour les fonction (initialiser la liste, allouerNoeud pou Liste chaînée [ par GoldenEye ] Qu'est ce que qu'une liste chaînée ?Merci liste chaînée et classes [ par yeager ] Bonjour!J'ai programmé pendant deux ans en C et actuellement j'étudie le C++. Pour moi une classe est l'équivalent d'une structure en plus évolué (hér Deux listes chaînées à comparer et modifier [ par poiuytrez3 ] Bonjour, je suis en train de créer un jeu à la shoot them up. De façon simplifié mon problème est le suivant :j'ai une liste chaînée qui contient des tri par insertion dans une liste chaînée [ par titi4659 ] Bonjour,j'ai un problème avec une liste chaînée.j'ai une liste d'element que j'arrive a récupéré mais je souhaiterai que lorsque je récupère un elemen Liste chainée Template maillon externe [ par Timidouveg ] Bonjour :)Je n'ai pas compris comment fonctionne les template. J'ai cherché des explications sur internet, mais j'avoue que ça m'échappe un peu :sJe s liste chaînée en langage c [ par youssefelmessari ] messieur j'aun un problème concernat la suprresion d'un élement sur la liste chaînée dont voici le doee source void suppression(void)// a r e v o i r suppression d'un noeud dans une liste chaînée avec C++ [ par saidkoukou ] Bonjour, je cherche un bout de code C++(ou une méthode) qui me permet de supprimer un noeud dans une liste chaînée. Merci de me répondre dans le temps Violation d'accès lors de la lecture de l'emplacement 0x00000000. [ par d0jones ] bonjour, j'ai un petit souci, quand j'essai d'accéder à la donnée de ma struct j'ai le message suivant : Exception non gérée à 0x01202029 dans ListTe [clos] mini projet language c [ par rajroujaabd ] j'ai un mini projet en programmation avec language c ,j'ai besoin d'aide . voila le sujet: PRINCIPE DU SERVICE GIS : Le service d'information géogra


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 4,399 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales