begin process at 2012 02 10 17:23:26
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Algorithme

 > 

Maths

 > 

quick sort


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

quick sort

mercredi 15 novembre 2006 à 21:36:48 | quick sort

eagleye

je voulais savoir comment utiliser quick sort pour trier une liste chainee pouvez vous me donner le code en c ?
mercredi 15 novembre 2006 à 21:57:22 | Re : quick sort

vecchio56

Administrateur CodeS-SourceS
Je crois que le quicksort à besoin d'un accès indexé aux éléments. Dans ce cas, c'est pas du tout adapté aux listes chainées.

_____________________________________
Un éditeur de ressources gratuit pour Windows

jeudi 16 novembre 2006 à 10:32:30 | Re : quick sort

ShareVB

salut,

le pire c'est ce que je croyait jusqu'à ce que je tombe sur un article qui parlait des listes chainées dans la glib...et en fait on peut faire du quicksort sur une liste chainéé...niveau perf ca doit pas forcément être nickel...mais bon : voici un code que j'ai fait pendant un cours de C...

note : ce code reproduit à peut près les list_head doublement chainées du noyau linux...très astucieux dans le principe : un inclu dans la liste dans les données et non les données dans la liste...

désolé pour la longueur que ca va donner :
dans main.c :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "list_head.h"

struct test {
    int az;
    double er;
    char m;

    LIST_ENTRY(l);
};
LIST_HEAD(test);

int compare(struct list_entry * e1,struct list_entry * e2)
{
    struct test *t1 = LIST_GET(e1,test,l);
    struct test *t2 = LIST_GET(e2,test,l);

    return (t1->m > t2->m ? 1 : -1);
}

int main()
{
    struct list_entry *p;
    struct list_entry *p2;
    struct test *t;
    int i;

    LIST_INIT(b);

    for (i = 0;i < 15;i++)
    {
        int j = rand() % 15;
        t = (struct test *)malloc(1 * sizeof(struct test));
        t->az = j;
        t->er = j;
        t->m = 'a'+j;
        LIST_INSERT_FIRST(b,t,test,l);
    }

    LIST_REMOVE_FIRST(b);

    p = b.first;
    while (p)
    {
        struct test *tp = LIST_GET(p,test,l);
        printf("%d %lf %c\n",tp->az,tp->er,tp->m);
        p2 = p;
        p=p->next;
    }

    printf("---\n");

    b.first = list_head_sort(b.first,compare);

    p = b.first;
    while (p)
    {
        struct test *tp = LIST_GET(p,test,l);
        printf("%d %lf %c\n",tp->az,tp->er,tp->m);
        p2 = p;
        p=p->next;
    }

    printf("---\n");

    while (p2)
    {
        struct test *tp = LIST_GET(p2,test,l);
        printf("%d %lf %c\n",tp->az,tp->er,tp->m);
        p2=p2->prev;
    }
    system("pause");
}

dans list_head.h :
#ifndef _LIST_HEAD_H_
#define _LIST_HEAD_H_

//store the needed element to be a double-linked list
struct list_entry {
    struct list_entry *next;
    struct list_entry *prev;
};

//get the offset of the member m in the struct t
#define OFFSET(t,m) (int)&(((struct t *)0)->m)
//get the offset of the member m in the struct pointed by p
#define OFFSET2(p,m) (int)((int)&((p)->m)-(int)(p))
//get the pointer to the beginning of the struct t given a pointer p to the member m
#define BASE_OF(p,t,m) (struct t *)((unsigned char *)p - OFFSET(t,m))

//declare a member m to make a struct a linked list with list_head
#define LIST_ENTRY(m) \
    struct list_entry m

//insert at the beginning of h, the element pointed by p of type t* which contains a member m of type struct list_entry
#define LIST_INSERT_FIRST(h,p,t,m) \
    (p)->m.prev = 0; \
    (p)->m.next = h.first; \
    (h).first = (struct list_entry *)((unsigned char*)(p)+OFFSET(t,m)); \
    if ((p)->m.next) \
        ((p)->m.next)->prev = h.first;

//insert element pointed by p after element pointed by p2 given the member m is the list_entry struct
#define LIST_INSERT_AFTER(p,p2,m) \
    (p)->m.prev = &((p2)->m); \
    (p)->m.next = (p2)->m.next; \
    (p2)->m.next = &((p)->m); \
    if ((p)->next) \
        (p)->next->prev = &((p)->m)

//insert element pointed by p before element pointed by p2 given the member m is the list_entry struct
#define LIST_INSERT_BEFORE(p,p2,m) \
    (p)->m.prev = (p2)->m.prev; \
    (p)->m.next = &((p2)->m); \
    (p2)->m.prev = &((p)->m); \
    if ((p)->prev) \
        (p)->prev->next = &((p)->m)

//remove element p given the member m is the list_entry struct
#define LIST_REMOVE(p,m) \
    if ((p)->m.prev) \
        (p)->m.prev->next = (p)->m.next; \
    if ((p)->m.next) \
        (p)->m.next->prev = (p)->m.prev; \

//remove the first element of h given the member m is the list_entry struct
#define LIST_REMOVE_FIRST(h) \
    if (h.first->next) \
        h.first->next->prev = 0; \
    h.first = h.first->next

//declare the list head struct whose first points to the first element of the list
#define LIST_HEAD() \
    struct list_head { \
        struct list_entry *first; \
    }

//init a variable b to be a list_head
#define LIST_INIT(b) \
    struct list_head b; b.first = 0

//get the pointer to the beginning of the struct t (data) given a pointer p to the member m
#define LIST_GET(p,t,m) \
    BASE_OF(p,t,m)

/*
* sort the list list with help of compare function
* list : list to sort
* compare : compare function to compare to element of list
* return a pointer to the first element in sorted list (so to the sorted list)
*/
struct list_entry *list_head_sort(struct list_entry *list,int(*compare)(struct list_entry *,struct list_entry *));

#endif

dans un list_head.c :
#include "list_head.h"

/*
* take two lists l1 and l2 and sort/merge them with the compare function compare
* l1, l2 : list to sort/merge
* compare : compare function to compare to elements
*/
static struct list_entry *list_head_sort_merge(struct list_entry *l1,struct list_entry *l2,int(*compare)(struct list_entry *,struct list_entry *))
{
    //l is used to insert elements at the end of the result list
    //ret is the beginning of the return list
    struct list_entry *l = 0,*ret = 0;
    //e is the element to insert to the result list
    struct list_entry *e = 0;

    //if no list to merge : return an empty list
    if (!l1 && !l2)
        return 0;

    //as long as we have an element in one of the lists
    while (l1 && l2)
    {
        //compare the current element of each list
        if (compare(l1,l2) > 0)
        {
            //element in l1 is greater than element in l2
            //so process l2
            e = l2;
            //pass to the next element of l2 since we will remove the current
            l2 = l2->next;
        }
        else
        {
            //element in l2 is greater than element in l1
            //so process l1
            e = l1;
            //pass to the next element of l1 since we will remove the current
            l1 = l1->next;
        }

        //if the result list is currently not empty
        if (l)
            //add the selected element at the end
            l->next = e;
        //else, e is the first element of the result list, so save it in the return value
        else
            ret = e;
       
        //the previous element of the new last is the current end of the result list
        e->prev = l;
        //the next element of the new last does not exist
        e->next = 0;
        //the new current end element of result list is the last selected element
        l = e;
    }

    //if there is elements yet in l1
    if (l1)
    {
        //append it to the end of the result list

        //if the result list is currently not empty
        if (l)
            //add l1 at the end
            l->next = l1;
        //else, l1 is the result list, so save it in the return value
        else
            ret = l1;
       
        //link the rest list to the end of result list
        l1->prev = l;
    }
    //if there is elements yet in l2
    else
    {
        //append it to the end of the result list

        //if the result list is currently not empty
        if (l)
            //add l2 at the end
            l->next = l2;
        //else, l2 is the result list, so save it in the return value
        else
            ret = l2;
       
        //link the rest list to the end of result list
        l2->prev = l;
    }

    return ret;
}

/*
* sort the list list with help of compare function
* list : list to sort
* compare : compare function to compare to element of list
* return a pointer to the first element in sorted list (so to the sorted list)
*/
struct list_entry *list_head_sort(struct list_entry *list,int(*compare)(struct list_entry *,struct list_entry *))
{
    //if we have a list to sort
    if (list)
    {
        //l1 : points to the middle of the list (skip one element at a time)
        //l2 : points to the end of the list (skip two elements at a time)
        struct list_entry *l1 = list,*l2 = l1->next;

        //as long as we are not at list end
        while (l2)
        {
            //l1 skip one element
            l1 = l1->next;
            //l2 skip two elements
            l2 = l2->next;
            l2 = (l2 ? l2->next : 0);
        }

        //split the two parts of the list (middle is pointed by l1)
        if (l1->prev)
            l1->prev->next = 0;
        l1->prev = 0;

        //if we have not only one element in list
        if (l1 != list)
            //process recursively the both part of list to sort locally
            return list_head_sort_merge(list_head_sort(list,compare),list_head_sort(l1,compare),compare);
        else
            //else return the one cell list
            return list;
    }
    else
        return 0;
}

bonne prog

ShareVB
jeudi 16 novembre 2006 à 12:36:23 | Re : quick sort

vecchio56

Administrateur CodeS-SourceS
Evidemment on peut le faire (quitte à transormer la liste en tableau, trier le tableau et transormer le tableau en liste, c'est sans doute encore plus rapide comme ça). Mais le tri n'est plus très 'quick' avec les listes chainées

_____________________________________
Un éditeur de ressources gratuit pour Windows

jeudi 16 novembre 2006 à 14:47:40 | Re : quick sort

ShareVB

salut,

non, non le code ci dessus fait du quick sort sans passer par un tableau...et je pense qui s'ils font cela dans la glib alors ca doit quand même être relativement efficace...

ShareVB


Cette discussion est classée dans : quick, sort


Répondre à ce message

Sujets en rapport avec ce message

ejecter un CD [ par Gô ] Bonjour,J dois faire un pity programme pour l'ecole de simulation de parcmétre avec différent tarif, ... (avec des class en plus) et j'aimerais bien q Filtrage de paquets [ par Kinamstrong ] Le filtrage de paquets consiste t il à surveiller en permanence ce qui sort sur la ligne (eth ou ppp) et analyser les paquets ????Si c ca comment fait tirage au sort [ par gemini010 ] slt g un pote qui aimerait créer un programme de tirage au sort en C mais il est debutant et n'as pas internet ( et moi je sais pas comment faire :( ) ecouter ce qui rentre et sort d'un port d'un pc [ par glipper ] Bonjour,j'ai installé Netcat sur mon pc il y a peu de temps, et j'ai trouvé ça amusant comme programme. Mais j'aimerais maintenant pouvoir lire tout c trier une liste (sort) [ par desquesa ] Bonjour, je cherche a trier une liste d'entiers, mais le pobleme est que par exemple isort trie de cette facon: 87,88,89,9,90,91,92....Je ne sais pas Fonction sort() de la STL [ par jul39dole ] Bonjour.J'utilise la STL et notamment les vecteurs. Le vecteur contient des objets de type class A (il s'agit d'une classe perso). Je cherche à trier erreur d'execution [ par caro_perf ] Bonjour, Voila mon probleme: en fait qd je lance mon executable ds le menu build de visual c++ (build/executer monexe.exe) il affiche la console c Avis au utilisateur de Borland 1 et de la fonction quick report [ par geag17 ] Est t'il possible d'intégrer des images au quick report de borland 1. Et à défaut de gérer les impressions de quick report pour y intégrer une tache d STL, <list> , sort() [ par iam_myst ] Bonjour a tous J'aimerais avoir des informations sur la fonctions sort(); Elle trie une certaine liste , mais selon quelle valeur ?? C'est facile a im Trier une liste avec sort de la STL [ par DrSteffie ] Bonjour à tous, Je suis un programmeur confirmé de C, et je suis passé depuis 6 mois au C++. Je n'utilise pas la plupart des avantages de ce langages


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
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 : 1,872 sec (3)

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