#include <stdio.h>
#include <stdlib.h>
#include "simple.h"
/*---------------------------------------------------------------*/
Liste *initialisation(void)
{
Liste *liste = malloc(sizeof(Liste));
if(liste == NULL)
exit(EXIT_FAILURE);
liste->premier = NULL;
return liste;
}
/*---------------------------------------------------------------*/
Bool est_ce_vide(Liste *lst)
{
if(lst->premier == NULL)
return vrai;
return faux;
}
/*---------------------------------------------------------------*/
void ajout_en_tete(Liste *lst, int nvnbr)
{
Element *nouveau = malloc(sizeof(Element));
if(lst == NULL || nouveau == NULL)
exit(EXIT_FAILURE);
nouveau->nombre = nvnbr;
nouveau->suivant = lst->premier;
lst->premier = nouveau;
}
/*---------------------------------------------------------------*/
void ajout_en_fin(Liste *lst, int nvnbr)
{
Element *nouveau = malloc(sizeof(*nouveau));
if(nouveau == NULL || lst == NULL)
exit(EXIT_FAILURE);
if(est_ce_vide(lst))
ajout_en_tete(lst, nvnbr);
else
{
Element *tmp = lst->premier;
nouveau->nombre = nvnbr;
nouveau->suivant = NULL;
while(tmp->suivant != NULL)
tmp = tmp->suivant;
tmp->suivant = nouveau;
}
}
/*---------------------------------------------------------------*/
void affiche_liste(Liste *lst)
{
if(lst == NULL)
exit(EXIT_FAILURE);
if(est_ce_vide(lst))
{
printf("\nLa Liste est vide.\n");
exit(EXIT_SUCCESS);
}
Element *actuel = lst->premier;
while(actuel != NULL)
{
printf("[%d] ", actuel->nombre);
actuel = actuel->suivant;
}
printf("\n");
}
/*---------------------------------------------------------------*/
void suppression_en_tete(Liste *lst)
{
if(lst == NULL)
exit(EXIT_FAILURE);
else if(!(est_ce_vide(lst)))
{
Element *elementASupprimer = lst->premier;
lst->premier = lst->premier->suivant;
free(elementASupprimer);
}
}
/*---------------------------------------------------------------*/
void suppression_en_fin(Liste *lst)
{
if(lst == NULL)
exit(EXIT_FAILURE);
if(!(est_ce_vide(lst)))
{
Element *elementASupprimer = lst->premier;
Element *precedent;
while(elementASupprimer->suivant != NULL)
{
precedent = elementASupprimer;
elementASupprimer = elementASupprimer->suivant;
}
precedent->suivant = NULL;
free(elementASupprimer);
}
}
/*---------------------------------------------------------------*/
Element *recherche_element(Liste *lst, int valeur)
{
if(lst == NULL)
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
while(tmp != NULL)
{
if(tmp->nombre == valeur)
return tmp;
tmp = tmp->suivant;
}
return NULL;
}
/*---------------------------------------------------------------*/
int nombre_occurence(Liste *lst, int valeur)
{
int i = 0;
Element *element = lst->premier;
if(lst == NULL)
exit(EXIT_FAILURE);
while(element != NULL)
{
if(element->nombre == valeur)
i++;
element = element->suivant;
}
return i;
}
/*---------------------------------------------------------------*/
void affiche_premier_element(Liste *lst)
{
printf("\nLe premier element de la liste : [%d]\n", lst->premier->nombre);
}
/*---------------------------------------------------------------*/
void affiche_dernier_element(Liste *lst)
{
if(lst == NULL)
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
while(tmp->suivant != NULL)
{
tmp = tmp->suivant;
}
printf("\nLe dernier element de la liste : [%d]\n", tmp->nombre);
}
/*---------------------------------------------------------------*/
Element *trouver_nieme_element(Liste *lst, int indice)
{
if(lst == NULL || indice >= (taille_liste(lst)))
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
int i = 0;
if(lst == NULL)
return NULL;
while(i < indice)
{
tmp = tmp->suivant;
i++;
}
return tmp;
}
/*---------------------------------------------------------------*/
int taille_liste(Liste *lst)
{
int taille = 0;
if(lst == NULL)
exit(EXIT_FAILURE);
if(est_ce_vide(lst))
return 0;
Element *tmp = lst->premier;
while(tmp != NULL)
{
tmp = tmp->suivant;
taille++;
}
return taille;
}
/*---------------------------------------------------------------*/
void vider_liste(Liste *lst)
{
if(lst == NULL)
exit(EXIT_FAILURE);
int taille = taille_liste(lst);
while(taille != 0)
{
suppression_en_tete(lst);
taille--;
}
}
/*---------------------------------------------------------------*/
void suppression_du_i_element(Liste *lst, int indice)
{
if(indice == 0)
exit(EXIT_FAILURE);
if(lst == NULL || indice >= (taille_liste(lst)))
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
Element *precedent;
for(int i = 0; i < indice; i++)
{
precedent = tmp;
tmp = tmp->suivant;
}
precedent->suivant = tmp->suivant;
free(tmp);
}
/*---------------------------------------------------------------*/
void ajout_au_milieu(Liste *lst, int indice, int valeur)
{
Element *nouveau = malloc(sizeof(Element));
if(lst == NULL || nouveau == NULL || indice >= (taille_liste(lst)))
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
Element *precedent;
for(int i = 0; i < indice; i++)
{
precedent = tmp;
tmp = tmp->suivant;
}
nouveau->nombre = valeur;
nouveau->suivant = precedent->suivant;
precedent->suivant = nouveau;
}
/*---------------------------------------------------------------*/
Liste *suppression_cible_valeur(Liste *lst, int valeur)
{
if(lst == NULL)
exit(EXIT_FAILURE);
Element *tmp = lst->premier;
Liste *nvliste = initialisation();
while(tmp != NULL)
{
if(tmp->nombre != valeur)
ajout_en_fin(nvliste, tmp->nombre);
tmp = tmp->suivant;
}
vider_liste(lst);
return nvliste;
}
/*Vous pouvez compléter votre bibliothèque avec des fonctions de tri,
de recherche de minimum, de maximum et bien d'autre choses...*/
Mon problème est que la fonction Liste *suppression_cible_valeur(Liste *lst, int valeur) si elle s'excecute très rapidement sur les listes de petites tailles , sur les grandes par contre le temps d'excecution est trop long (par exemple ~30s sur 100000). La fonction doit parcourir toute la chaine à la recherche de la valeur ciblé et en même temps copier les autres valeurs dans un autre liste et ensuite liberer l'ancienne liste avant de retourne la nouvelle . J'avoue je l'ai mal coder celle-là .Si vous pouvez m'aider à l'optimiser un peu se serait cool.
Ça montre à l'évidence un problème de conception ! On ne fait pas n'importe quoi avec une liste chaînée, on peut s'en servir pour simuler des piles ou des files sinon, c'est inadapté.
Ici tu t'en sers pour gérer des nombres.
Il faudrait qu'elle soit triée en fonction de "nombre".
Tu ajoutes un nombre en insérantun noeud au bon endroit.
Tu supprimes une valeur en supprimantle/les noeuds concernés.
Jamais de recopies des bonnes valeurs, c'est justement ça l'intérêt des listes chaînées.
Dernière choses, pour le dernier élément, tu as tout à fait le droit d'avoir un pointeur sur ce dernier élément, ça gagne énormément de temps.
- Edité par joel76 23 mars 2020 à 9:03:13
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Oui mais comme je suis en apprentissage, je me dis que maitriser les listes simplement chainées avant de passer aux doublement chainées serait plus avantageux que je de sauter directement à la suite
Je suis d'accord que tu dois maîtriser les listes simplement chaînées en premier.
Si tu supprimes le premier élément de ta liste, tu le sais et tu agit en conséquence.
Mais si tu ne sais pas où se trouve l'élément à supprimer dans ta liste, il faut que tu vérifies que:
+ soit la liste ne contient qu'un seul élément.
+ que tu supprimes le premier élément sans le savoir.
Pour cela, tu dois tester si l'élément à supprimer (tmp) est égal à lst->premier (tu testes les pointeurs).
Si c'est le cas, tu dois faire lst->premier = tmp->suivant
Sinon, tu dois faire precedent->suivant = tmp->suivant
et les deux avant le free()
et à ce stade, ce n'est pas important si ce suivant est NULL.
Si tu dois supprimer plusieurs éléments dans ta liste, il ne faut pas modifier precedent tout de suite car il est toujours le précédent du suivant de ce que tu viens de supprimer.
(est-ce assez clair? ... )
Tu ne dois en aucun cas te fier au contenu de l'élément que tu viens de libérer avec free().
- Edité par PierrotLeFou 23 mars 2020 à 16:29:10
Le Tout est souvent plus grand que la somme de ses parties.
Slt merci beaucoup pour vos explications et PierrotLeFou pour ton code je l'ai testé en il marche. Dites comment faites vous pour etre aussi bon en programmation ?
Pour ce qui est de ta première consigne il ne passe rien quand j'essaie de supprimer une liste vide , du moins en apparence.
Pour la seconde , en testant avec un seul élément celui si est simplement retiré de la liste et la fonction affiche_liste me signale que la liste est vide. Et pour ce qui est supprimer un élément qui ne se trouve pas dans la liste, j'ai pas non plus d'erreur de ce côté.
Pour les troisième et quatrième consignes , toutes les occurences de la valeur ciblée sont simplement retirées de la liste. Pour le premier cas , la fonction affiche_liste m'affiche ce qui reste de la liste et pour le deuxième elle me signale que la liste est vide.
J'y est jetté un coup d'oeil et il est super ce site. Je l'ajoute direct à mes favoris. Merci beaucoup.
- Edité par BamAss 25 mars 2020 à 17:38:12
Nobody Is Anonyme!!!
Structures de données : listes chainées
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Nobody Is Anonyme!!!
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Nobody Is Anonyme!!!
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Nobody Is Anonyme!!!
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Le Tout est souvent plus grand que la somme de ses parties.
Nobody Is Anonyme!!!
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Nobody Is Anonyme!!!
Le Tout est souvent plus grand que la somme de ses parties.
Nobody Is Anonyme!!!
Le Tout est souvent plus grand que la somme de ses parties.
Nobody Is Anonyme!!!
Le Tout est souvent plus grand que la somme de ses parties.
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
Nobody Is Anonyme!!!