Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • e87374u/projet_pne
1 result
Select Git revision
Show changes
Commits on Source (3)
PROJET 2 @ f43476f5
Subproject commit f43476f568470cac7811c99454c7275fdf5c99cd
#pragma once
#include "list.h"
/* file mode : text or binary */
typedef enum file_mode { TEXT, BINARY } file_mode_t;
/**
* @brief read a list from a text or binary file acording to the mode
* @param mode : TEXT or BIN
* @param data_read_fct : ptr to fct that reads datum from file fd ; fct's parameters : (fd, mode)
* @param del_fct : ptr to fct that deallocate datum's memory, ; fct's parameter (datum)
*/
list_t * read_list ( file_mode_t mode, void * (*read_fct) (), void (*del_fct) () );
/**
* @brief write a list into a text or binary file acording to the mode
* @param mode : TEXT or BIN
* @param data_write_fct : ptr to fct that writes datum into file fd ; fct's parameters : (datum, fd, mode)
*/
void write_list ( list_t * L, file_mode_t mode, void (*write_fct) () );
\ No newline at end of file
#pragma once
#include "list.h"
#include <stdbool.h>
#define UNDEF -2
/** Des redondances possibles avec d'autres TAs ! */
typedef struct {
char * title; // Nom de la tâche
double life; // Durée de la tâche
int input_degree; // Son degré de dépendance
int output_degree; // Les tâches qui en dépendent
int rank; // Rang de la tâche
int dyn_input_degree; // Facilité de prog
list_t * precedence; // Les tâches précédentes
list_t * posteriority; // Les tâches ultérieures
double au_plus_tot; // Date au plus tôt
double au_plus_tard; // Date au plus tard
double marge_totale; // Marge totale
double marge_libre; // Marge libre
bool critique; // Une tâche critique ?
} job_t;
job_t * new_empty_job();
job_t * new_job(char * title);
void free_job(job_t ** ptrJ);
void view_job ( job_t * J );
char * get_job_title(job_t * J);
void set_job_title(job_t * J, char * title);
double get_job_life(job_t * J);
void set_job_life(job_t * J, double life);
int get_job_iDegree(job_t * J);
void set_job_iDegree(job_t * J, int iDegree);
void incr_job_iDegree(job_t * J);
void decr_job_iDegree(job_t * J);
int get_job_oDegree(job_t * J);
void set_job_oDegree(job_t * J, int oDegree);
void incr_job_oDegree(job_t * J);
void decr_job_oDegree(job_t * J);
int get_job_rank(job_t * J);
void set_rank(job_t * J, int rank);
int titleJobCmp(job_t * J1, job_t * J2);
int iDegreeJobCmp(job_t * J1, job_t * J2);
int oDegreeJobCmp(job_t * J1, job_t * J2);
int rangJobCmp(job_t * J1, job_t * J2);
#pragma once
#include <stdbool.h>
#include "list_elm.h"
typedef struct list {
list_elm_t * head;
list_elm_t* tail;
int numelm;
} list_t;
list_t * new_list();
void del_list ( list_t * * L, void (*ptrf) () );
bool empty_list ( list_t * L );
list_elm_t * get_head ( list_t * L );
list_elm_t * get_tail ( list_t * L );
void view_list ( list_t * L, void (*ptrf)() );
void cons ( list_t * L, void * data );
void queue ( list_t * L, void * data );
void ordered_insert ( list_t * L, void * data, int (*cmpFct)() );
int get_numelm(list_t * L);
// void take_out(struct list_t * L, void * D);
void quick_sort(list_t * L, int (*cmpFct)());
void find(list_t * L, void ** ptrKey, int (*cmpFct)(), void (*delFct)());
void del_list(list_t ** ptrL, void (*ptrf) ());
void clean(list_t * L);
bool is_empty(list_t * L);
#pragma once
typedef struct list_elm {
void * data;
struct list_elm * suc, * pred;
} list_elm_t;
list_elm_t * new_list_elm ( void * data );
/**
* @brief delete the list element E and optionnaly its datum
* @param ptrf : a ptr to fct that deallocates datum's memory ;
* if ptrf is NULL, datum is not freed
*/
void del_list_elm( list_elm_t * * E, void (*ptrf)() );
list_elm_t * get_suc ( list_elm_t * E );
list_elm_t * get_pred ( list_elm_t * E );
void * get_data ( list_elm_t * E );
void set_suc ( list_elm_t * E, list_elm_t * S );
void set_pred ( list_elm_t * E, list_elm_t * P );
void set_data ( list_elm_t * E, void * data );
void view_list_elm ( list_elm_t * E, void (*ptrf)() );
#pragma once
#define EPSILON 0.00000001// ε = 10^{-8}
/** Integer comparaison */
int int_cmp ( int * a, int * b );
/** Double comparaison */
int double_cmp ( double * a, double * b );
\ No newline at end of file
#pragma once
#include "list.h"
void ranking(list_t * G);
void prune(list_t * G);
void marges(list_t * G);
BDIR = bin
IDIR = include
ODIR = obj
SDIR = src
CC = gcc
# Le déboggage en toutes circonstances grâce à :: -D _DEBUG_
# que l'on peutarêter à tout moment grâce à :: -U _DEBUG_
CFLAGS = -Wall -I$(IDIR) -g -c
LFLAGS = -lm
PROG = $(BDIR)/mpm
_DEPS = job.h list.h list_elm.h outils.h #rank.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJS = db.o io.o job.o list.o list_elm.o main.o outils.o #rank.o
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
.PHONY : run all dirs clean delete
run : all
./$(PROG)
all : dirs $(OBJS)
$(CC) -o $(PROG) $(OBJS) $(LFLAGS)
dirs :
mkdir -p $(ODIR) $(BDIR)
$(ODIR)/%.o : $(SDIR)/%.c $(DEPS)
$(CC) $(CFLAGS) -o $@ $<
clean :
rm -rf $(ODIR)
delete : clean
rm -rf $(BDIR)
\ No newline at end of file
File added
File added
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "db.h"
#include "list.h"
#include "list_elm.h"
list_t * read_list( file_mode_t mode, void * (*read_fct) (), void (*del_fct) () ) {
FILE * fd;
char fname[20];
list_t * L = new_list();
if (mode == TEXT) {// Open file in TEXT mode
printf( "\t\tRead list from text file (.txt)\n\tfile name :" );
scanf( "%s", fname );
fd = fopen( fname, "rt" );
}
else {// open file in BIN mode
printf( "\t\tRead list from binary file (.bin)\n\tfile name :" );
scanf( "%s", fname );
fd = fopen( fname, "rb" );
}
//todo
void * datum;
while ((datum = read_fct(fd, mode)) != NULL) {
queue(L, datum);
}
list_elm_t * E = get_tail(L);
if (E != NULL && empty_list(E->data)) {
list_elm_t * T = get_pred(E);
if (T != NULL) {
set_suc(T, NULL);
L->tail = T;
} else {
L->head = L->tail = NULL;
}
del_list_elm(&E, del_fct);
}
/** TODO parcourir le fichier pour y collecter les formulaires et les ranger dans la L
ATTENTION :
il est **possible** que vous créiez un élément de trop (un formulaire vide) en fin de liste.
Il faut alors penser à le supprimer grâce au code suivant :
E = get_tail (L);
struct elmlist * T = getPred(E);
set_suc(T, NULL);
L->tail = T;
del_elmlist(E, ptr_del);
*/
fclose(fd);
return L;
}
void write_list( list_t * L, file_mode_t mode, void (*write_fct) () ) {
FILE * fd;
char fname[20];
if (mode == TEXT) {
printf( "\t\tWrite list to text file (.txt)\n\tfile name :"), scanf( "%s", fname );
fd = fopen( fname, "wt" );
} else {
printf("\t\tWrite list to binary file (.bin)\n\tfile name :"), scanf( "%s", fname );
fd = fopen(fname, "wb" );
}
for (list_elm_t * elm = get_head(L); elm != NULL; elm = elm->suc){
write_fct(elm->data, mode, fd);
}
/// @todo Parcourir L et écrire les formulaires grâce à data_write_fct
fclose(fd);
}
#include "list.h"
#include "list_elm.h"
#include "job.h"
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
list_t * read_graph ( char * filename ) {
FILE * fd = fopen ( filename, "rt" );
list_t * G = new_list ( );
assert ( fd && G );
char job_name [ BUFSIZ ];
while ( !feof ( fd ) ) {
fscanf ( fd, " %s", job_name);
if ( !strcmp (job_name, "NIL" ) ) continue;
job_t * J = new_job ( job_name );
/** @note
À l'appel J pointe sur le job que l'on vient de créer.
FIND retrouve le job J dans la liste G des jobs grâce à la fonction titleJobCmp.
Si ce job n'est pas dans la liste G alors
le job pointé par J est enregistré dans G
Si ce job est déjà dans G alors
le job pointé par J est supprimé grâce à free_job
puis le pointeur de J est réassigné sur le job trouvé dans G
*/
find ( G, ( void ** ) &J, &titleJobCmp, &free_job );
fscanf ( fd, "%lf", &(J->life) );
/** @note
Enregistrement des préséances
*/
job_t * predJ;
fscanf( fd, " %s", job_name );
while ( strcmp ( job_name, "NIL" ) ) {
predJ = new_job ( job_name );
//SOUVIENS SI &TITTLEJOBCMP = &SETJOBTITLE
find ( G, (void **) &predJ, &titleJobCmp, &free_job );
ordered_insert ( predJ->posteriority, J, &titleJobCmp );
incr_job_oDegree ( predJ );
ordered_insert ( J->precedence, predJ, &titleJobCmp );
incr_job_iDegree ( J );
fscanf ( fd, " %s", job_name );
}
/** @note valeurs par défaut des autres champs */
J->dyn_input_degree = J->input_degree;
J->rank = UNDEF;
J->au_plus_tard = UNDEF;
J->au_plus_tot = UNDEF;
J->marge_totale = UNDEF;
J->critique = false;
}
view_list(G,&view_job);
return G;
}
static void partition(list_t * L, elmlist_t * pivot, list_t * val_inf, list_t * val_sup, int (*cmpFct)(void*, void*)) {
for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) {
if (cmpFct(get_data(cur), get_data(pivot)) < 0)
queue(val_inf, get_data(cur));
else
queue(val_sup, get_data(cur));
}
}
void quick_sort(list_t * L, int (*cmpFct)(void*, void*)) {
assert(L && cmpFct);
if (L->numelm > 1) {
//CONFIRMER LE STRUCT
struct list_elm_t * pivot = get_head(L);
L->head = get_suc(pivot);
pivot->pred = NULL;
pivot->suc = NULL;
/** @note
* La listes des données inférieures à pivot
* La listes des données supérieures à pivot
*/
list_t * val_inf_pivot = new_list();
list_t * val_sup_pivot = new_list();
/** @note Déplacement des données de L dans val_inf_pivot et val_sup_pivot */
partition(L,pivot,val_inf_pivot,val_sup_pivot,cmpFct);
/** @note On supprimer les éléments de L sans supprimer ni L ni les jobs */
// elmlist_t * S;
// for(elmlist_t * E = L->head; E; E = S){
// S = E->suc;
// free(E);
// }
/** @note
* Si la partie inf est vide alors L commence par le pivot
* Sinon on tri grâce à cmpFct la partie inf puis on ajoute en queue le pivot
*/
if (is_empty(val_inf_pivot)) {
L->head = pivot;
L->tail = pivot;
L->numelm = 1;
} else {
quick_sort(val_inf_pivot, cmpFct);
L->head = val_inf_pivot->head;
L->tail = val_inf_pivot->tail;
L->numelm = val_inf_pivot->numelm;
pivot->pred = L->tail;
L->tail->suc = pivot;
L->tail = pivot;
L->numelm += 1;
}
/** @note
* Si la partie sup n'est pas vide alors
* On la trie puis on la concatène à la partie inf
*/
if (!is_empty(val_sup_pivot)) {
quick_sort(val_sup_pivot, cmpFct);
val_sup_pivot->head->pred = pivot;
set_suc(pivot, val_sup_pivot->head);
L->tail = val_sup_pivot->tail;
L->numelm += val_sup_pivot->numelm;
}
free(val_inf_pivot);
free(val_sup_pivot);
}
}
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "job.h"
#include "list.h"
job_t * new_empty_job ( ) {
job_t * J = calloc ( 1, sizeof (job_t ) );
assert( J );
J->precedence = new_list ( );
J->posteriority = new_list ( );
J->rank = UNDEF;
J->au_plus_tard = UNDEF;
J->au_plus_tot = UNDEF;
J->marge_totale = UNDEF;
J->critique = false;
return J;
}
job_t * new_job ( char * title ) {
job_t * J = new_empty_job ( );
J->title = strdup ( title );
return J;
}
void free_job(job_t ** ptrJ ) {
assert ( ptrJ && *ptrJ );
if( (*ptrJ)->title ) free ( (*ptrJ)->title );
free ( *ptrJ );
*ptrJ = NULL;
}
void view_job ( job_t * J ) {
printf ( "JOB %s\n\tpreceeded by [", get_job_tilte ( J ) );
for(elmlist_t * E = get_head ( J->precedence ); E; E = get_suc ( E ) ) {
printf ( " %s", get_job_tilte ( get_data ( E ) ) );
}
printf ( " ]\n" );
// if ( !get_numelm ( J->posteriority ) ) printf ( "\t" );
printf ( "\tfollowed by [" );
for(elmlist_t * E = get_head(J->posteriority); E; E = get_suc(E)){
printf(" %s", get_job_tilte(get_data(E)));
}
printf ( " ]\n" );
printf ( "\tiDeg=%d\toDeg=%d\tlife=%2.2lf", J->input_degree, J->output_degree, J->life );
printf ( "\trank=" );
if ( J->rank == UNDEF ) printf ( "U" ); else printf ( "%d", J->rank );
printf ( "\tearly=" );
if(J->au_plus_tot == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tot );
printf ( "\tlate=" );
if(J->au_plus_tard == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tard );
printf ( "\ttotale= " );
if ( J->marge_totale == UNDEF ) printf("U"); else printf ( "%2.2lf", J->marge_totale );
printf ( "\tcritical= " );
if ( J->critique ) printf("Y\n"); else printf ( "N\n" );
}
#include "job.h"
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
job_t * new_empty_job(){
job_t * J = calloc ( 1, sizeof (job_t ) );
assert( J );
J->precedence = new_list ( );
J->posteriority = new_list ( );
J->rank = UNDEF;
J->au_plus_tard = UNDEF;
J->au_plus_tot = UNDEF;
J->marge_totale = UNDEF;
J->critique = false;
return J;
}
job_t * new_job(char * title){
job_t * J = new_empty_job ( );
J->title = strdup ( title );
return J;
}
void free_job(job_t ** ptrJ){
assert ( ptrJ && *ptrJ );
if( (*ptrJ)->title ) free ( (*ptrJ)->title );
free ( *ptrJ );
*ptrJ = NULL;
}
void view_job ( job_t * J ) {
printf ( "JOB %s\n\tpreceeded by [", get_job_tilte ( J ) );
for(elmlist_t * E = get_head ( J->precedence ); E; E = get_suc ( E ) ) {
printf ( " %s", get_job_tilte ( get_data ( E ) ) );
}
printf ( " ]\n" );
// if ( !get_numelm ( J->posteriority ) ) printf ( "\t" );
printf ( "\tfollowed by [" );
for(elmlist_t * E = get_head(J->posteriority); E; E = get_suc(E)){
printf(" %s", get_job_tilte(get_data(E)));
}
printf ( " ]\n" );
printf ( "\tiDeg=%d\toDeg=%d\tlife=%2.2lf", J->input_degree, J->output_degree, J->life );
printf ( "\trank=" );
if ( J->rank == UNDEF ) printf ( "U" ); else printf ( "%d", J->rank );
printf ( "\tearly=" );
if(J->au_plus_tot == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tot );
printf ( "\tlate=" );
if(J->au_plus_tard == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tard );
printf ( "\ttotale= " );
if ( J->marge_totale == UNDEF ) printf("U"); else printf ( "%2.2lf", J->marge_totale );
printf ( "\tcritical= " );
if ( J->critique ) printf("Y\n"); else printf ( "N\n" );
}
char * get_job_title(job_t * J) {
assert(J);
return J->title;
}
void titleJobCmp(job_t * J, char * title){
}
void set_job_title(job_t * J, char * title) {
assert(J && title);
if(J->title)
free(J->title);
J->title = strdup(title);
}
double get_job_life(job_t * J) {
assert(J);
return J->life;
}
void set_job_life(job_t * J, double life) {
assert(J);
J->life = life;
}
int get_job_iDegree(job_t * J) {
assert(J);
return J->input_degree;
}
void set_job_iDegree(job_t * J, int iDegree) {
assert(J);
J->input_degree = iDegree;
}
void incr_job_iDegree(job_t * J) {
assert(J);
J->input_degree++;
}
void decr_job_iDegree(job_t * J) {
assert(J);
J->input_degree--;
}
\ No newline at end of file
#include "job.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//TOUS EST CHANGee
int get_job_oDegree(job_t * J) {
assert(J);
return J->output_degree;
}
void set_job_oDegree(job_t * J, int oDegree) {
assert(J);
J->output_degree = oDegree;
}
void incr_job_oDegree(job_t * J) {
assert(J);
J->output_degree++;
}
void decr_job_oDegree(job_t * J) {
assert(J);
J->output_degree--;
}
int get_job_rank(job_t * J) {
assert(J);
return J->rank;
}
void set_rank(job_t * J, int rank) {
assert(J);
J->rank = rank;
}
int titleJobCmp(job_t * J1, job_t * J2) {
assert(J1 && J2);
return strcmp(J1->title, J2->title);
}
int iDegreeJobCmp(job_t * J1, job_t * J2) {
assert(J1 && J2);
return J1->input_degree - J2->input_degree;
}
int oDegreeJobCmp(job_t * J1, job_t * J2) {
assert(J1 && J2);
return J1->output_degree - J2->output_degree;
}
int rangJobCmp(job_t * J1, job_t * J2) {
assert(J1 && J2);
return J1->rank - J2->rank;
}
#include <stdlib.h>
#include <assert.h>
#include "list.h"
#include "list_elm.h"
list_t * new_list() {
list_t * L = calloc(1, sizeof(list_t));
assert(L);
L->head = NULL;
L->tail = NULL;
L->numelm = 0;
return L;
}
void del_list(list_t ** L, void (*ptr_del)(void *)) {
assert(L && *L);
list_t * list = *L;
list_elm_t * E = list->head;
while (E) {
list_elm_t * temp = E;
E = E->suc;
if(ptr_del) {
ptr_del(temp->data);
}
free(temp);
}
free(*L);
*L = NULL;
}
bool empty_list(list_t * L) {
assert(L);
return L->numelm == 0;
}
list_elm_t * get_head(list_t * L) {
assert(L);
return L->head;
}
list_elm_t * get_tail(list_t * L) {
assert(L);
return L->tail;
}
void view_list(list_t * L, void (*ptr_view)(void *)) {
assert(L && ptr_view);
for (list_elm_t * E = L->head; E != NULL; E = get_suc(E)) {
ptr_view(E->data);
}
}
void cons(list_t * L, void * data) {
list_elm_t * E = new_list_elm(data);
E->suc = L->head;
if (L->head != NULL) {
L->head->pred = E;
}
L->head = E;
if (L->tail == NULL) {
L->tail = E;
}
L->numelm++;
}
void queue(list_t * L, void * data) {
list_elm_t * E = new_list_elm(data);
if(empty_list(L)) {
L->head = E;
L->tail = E;
} else {
L->tail->suc = E;
E->pred = L->tail;
L->tail = E;
}
L->numelm++;
}
void insert_after(list_t * L, void * data, list_elm_t * elm) {
if(elm == NULL) return;
list_elm_t * E = new_list_elm(data);
E->suc = elm->suc;
E->pred = elm;
if(elm->suc != NULL) {
elm->suc->pred = E;
} else {
L->tail = E;
}
elm->suc = E;
L->numelm++;
}
void ordered_insert(list_t * L, void * data, int (*cmpFct)(void*, void*)) {
if(empty_list(L) || cmpFct(L->head->data, data) > 0) {
cons(L, data);
} else {
list_elm_t * current = L->head;
while(get_suc(current) != NULL && cmpFct(get_suc(current)->data, data) <= 0) {
current = get_suc(current);
}
insert_after(L, data, current);
}
}
#include "list_1 (1).h"
#include "list"
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
typedef struct{
elmlist_t * head;
elmlist_t * tail;
int numelm;
} list_t ;
// Create an empty list
list_t * new_list(){
list_t * t = calloc(1, sizeof(list_t));
assert(t);
return t;
}
// Delete list, its elements and possibly the data
//DOIT CONFIRMER LE STRUCT
void del_list(list_t ** ptrL, void (*ptrf) ()){
assert(ptrL && *ptrL);
list_t * L = *ptrL;
if(ptrf){
for(elmlist_t * E = L->head; E; ){
elmlist_t * T = E;
E = E->suc;
(*ptrf)(T->data);
free(T);
}
}
} else {
for(elmlist_t * E = L->head; E ; ){
elmlist_t * T = E;
E = E->suc;
free(T);
}
free(*ptrL);
(*ptrL) = NULL;
}
// Clean list; delete its elments but keep data and the list
void clean(list_t * L){
assert(L);
elmlist_t *curr = L->head;
while (curr != NULL) {
elmlist_t *temp = curr;
curr = curr->suc;
free(temp);
}
L->head = NULL;
L->tail = NULL;
L->numelm = 0;
}
// Is list L empty ?
bool is_empty(list_t * L){
assert(L);
if (L->numelm == 0) return true;
return false;
}
elmlist_t * get_head(list_t * L){
assert(L);
L = L->head;
return L;
}
elmlist_t * get_tail(list_t * L){
assert(L);
L = L->tail;
return L;
}
\ No newline at end of file
#include "list_1 (1).h"
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
// Gimme the number of elements of L
int get_numelm(struct list_t * L){
assert(L);
return L->numelm;
}
// Take out the data D of the list L if it is present
void take_out(struct list_t * L, void * D){
assert(L);
elmlist_t * current = L->head;
while (current != NULL) {
if (get_data(current) == D) {
elmlist_t * p = get_pred(current);
elmlist_t * s = get_suc(current);
// Update predecessor’s successor
if (p) set_suc(p, s);
else L->head = s; // current was head
// Update successor’s predecessor
if (s) set_pred(s, p);
else L->tail = p; // current was tail
free(current);
L->numelm--;
return;
}
current = get_suc(current);
}
}
// Add a element holding data to the head of L
void cons(struct list_t * L, void * data){
elmlist_t * E = calloc(1, sizeof(elmlist_t));
assert(L && E);
set_data(E, data);
set_suc(E, L->head);
set_head(L, E);
if(is_empty(L)) L->tail = E;
L->numelm += 1;
}
// Add a element holding data to the tail of L
void queue(struct list_t * L, void * data){
assert(L);
elmlist_t * E = calloc(1, sizeof(elmlist_t));
assert(E);
set_data(E, data);
E->suc = NULL;
if (is_empty(L)) {
E->pred = NULL;
L->head = E;
L->tail = E;
} else {
E->pred = L->tail;
L->tail->suc = E;
L->tail = E;
}
L->numelm++;
}
// Insert in L a element holding data wrt order given by cmp_ptrf
void ordered_insert(struct list_t * L, void * data, int (*cmp_ptrf)()){
assert(L && cmp_ptrf);
elmlist_t * E = calloc(1, sizeof(elmlist_t));
assert(E);
set_data(E, data);
// if list is empty, simply add the element
if (is_empty(L)) {
E->pred = E->suc = NULL;
L->head = L->tail = E;
L->numelm++;
return;
}
}
// Elements qui sont moins = val_inf et le reste val_sup.
static void partition(list_t * L, elmlist_t * pivot, list_t * val_inf, list_t * val_sup, int (*cmpFct)(void*, void*)) {
for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) {
if (cmpFct(get_data(cur), get_data(pivot)) < 0)
queue(val_inf, get_data(cur));
else
queue(val_sup, get_data(cur));
}
}
void quick_sort(list_t * L, int (*cmpFct)(void*, void*)) {
assert(L && cmpFct);
if (L->numelm > 1) {
elmlist_t * pivot = get_head(L);
L->head = get_suc(pivot);
pivot->pred = NULL;
pivot->suc = NULL;
/** @note
* La listes des données inférieures à pivot
* La listes des données supérieures à pivot
*/
list_t * val_inf_pivot = new_list();
list_t * val_sup_pivot = new_list();
/** @note Déplacement des données de L dans val_inf_pivot et val_sup_pivot */
partition(L,pivot,val_inf_pivot,val_sup_pivot,cmpFct);
/** @note On supprimer les éléments de L sans supprimer ni L ni les jobs */
// elmlist_t * S;
// for(elmlist_t * E = L->head; E; E = S){
// S = E->suc;
// free(E);
// }
/** @note
* Si la partie inf est vide alors L commence par le pivot
* Sinon on tri grâce à cmpFct la partie inf puis on ajoute en queue le pivot
*/
if (is_empty(val_inf_pivot)) {
L->head = pivot;
L->tail = pivot;
L->numelm = 1;
} else {
quick_sort(val_inf_pivot, cmpFct);
L->head = val_inf_pivot->head;
L->tail = val_inf_pivot->tail;
L->numelm = val_inf_pivot->numelm;
pivot->pred = L->tail;
L->tail->suc = pivot;
L->tail = pivot;
L->numelm += 1;
}
/** @note
* Si la partie sup n'est pas vide alors
* On la trie puis on la concatène à la partie inf
*/
if (!is_empty(val_sup_pivot)) {
quick_sort(val_sup_pivot, cmpFct);
val_sup_pivot->head->pred = pivot;
pivot->suc = val_sup_pivot->head;
L->tail = val_sup_pivot->tail;
L->numelm += val_sup_pivot->numelm;
}
free(val_inf_pivot);
free(val_sup_pivot);
}
}
// void quick_sort(list_t * L, int (*cmpFct)()){
// if (L == NULL || L->numelm < 2)
// return;
// elmlist_t * pivotNode = L->head;
// void * pivotData = pivotNode->data;
// list_t * less = new_list();
// list_t * greater = new_list();
// for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) {
// if (cur == pivotNode)
// continue;
// if (cmpFct(cur->data, pivotData) < 0)
// queue(less, cur->data);
// else
// queue(greater, cur->data);
// }
// clean(L);
// quick_sort(less, cmpFct);
// quick_sort(greater, cmpFct);
// for (elmlist_t * node = less->head; node != NULL; node = node->suc)
// queue(L, node->data);
// queue(L, pivotData);
// for (elmlist_t * node = greater->head; node != NULL; node = node->suc)
// queue(L, node->data);
// free(less);
// free(greater);
// }
void view_list(list_t * L, void (*ptrf)()) {
assert(L && ptrf);
elmlist_t * curr = L->head;
while (curr) {
ptrf(get_data(curr));
curr = curr->suc;
}
}
// Return un ptr vers element else NULL
void find(list_t * L, void ** ptrKey, int (*cmpFct)(), void (*delFct)()) {
assert(L && ptrKey && cmpFct);
elmlist_t * curr = L->head;
while (curr) {
if (cmpFct(get_data(curr), *ptrKey) == 0) {
if (delFct)
delFct(ptrKey);
*ptrKey = get_data(curr);
return;
}
curr = curr->suc;
}
}