Listes simplement chaînées
Dave1987
Messages postés
8
Statut
Membre
-
Dave1987 Messages postés 8 Statut Membre -
Dave1987 Messages postés 8 Statut Membre -
Bonjour, ma question se porte sur le langage C et plus précisément sur les listes simplement chaînées. Je souhaiterai donc créer une fonction qui permettra de supprimer un élément qui est présent plusieurs fois dans ma liste chaînée.
Par exemple, je suppose que je ne sais pas quel sont les éléments qu'il y a dans ma liste chaînée mais si il y a par exemple un 12 ou plusieurs 12, alors il faut les supprimer.
j'ai essayé avec le programme suivant (ma liste contient 31 31 31 69 31 33 15)
Donc voila la fonction de suppression et d'affichage (pas la peine que je donne les fonctions avec lesquelles j'ai introduit les éléments dans la liste)
langage C
void sup_Multipl(pile *p, int valeur) {
while(p != NULL) {
if(p->val == valeur) {
pile *tmp = p;
tmp = p->next;
free(p);
p = tmp;
}
else {
p = p->next;
}
}
}
langage C
void Afficher_Pile(pile *p) {
pile *afficheur = p;
printf("les elements de la liste sont : \n");
while(afficheur != NULL) {
printf("%d\n", *afficheur);
afficheur = afficheur->next;
}
}
main.C
langage C
pile *Mapile = NULL;
sup_Multipl(Mapile, 31);
printf("Et donc ");
Afficher_Pile(Mapile);
A la compilation j'ai ceci:
0
4007312
4007296
69
4007280
33
15
Donc ma fonction sup_Multipl ne fonctionne pas vraiment puisque les 31 sont supprimés mais il reste toujours des crasses, je pense que c'est dû à la non initialisation après suppression des 31 du pointeur de début de chaîne et des next des éléments non supprimés.
Si quelqu'un peut m'aider ça sera vraiment bienvenue parce que ça fait une semaine que je cherche et j'arrive pas à trouver la solution. MERCI d'avance.
Par exemple, je suppose que je ne sais pas quel sont les éléments qu'il y a dans ma liste chaînée mais si il y a par exemple un 12 ou plusieurs 12, alors il faut les supprimer.
j'ai essayé avec le programme suivant (ma liste contient 31 31 31 69 31 33 15)
Donc voila la fonction de suppression et d'affichage (pas la peine que je donne les fonctions avec lesquelles j'ai introduit les éléments dans la liste)
langage C
void sup_Multipl(pile *p, int valeur) {
while(p != NULL) {
if(p->val == valeur) {
pile *tmp = p;
tmp = p->next;
free(p);
p = tmp;
}
else {
p = p->next;
}
}
}
langage C
void Afficher_Pile(pile *p) {
pile *afficheur = p;
printf("les elements de la liste sont : \n");
while(afficheur != NULL) {
printf("%d\n", *afficheur);
afficheur = afficheur->next;
}
}
main.C
langage C
pile *Mapile = NULL;
sup_Multipl(Mapile, 31);
printf("Et donc ");
Afficher_Pile(Mapile);
A la compilation j'ai ceci:
0
4007312
4007296
69
4007280
33
15
Donc ma fonction sup_Multipl ne fonctionne pas vraiment puisque les 31 sont supprimés mais il reste toujours des crasses, je pense que c'est dû à la non initialisation après suppression des 31 du pointeur de début de chaîne et des next des éléments non supprimés.
Si quelqu'un peut m'aider ça sera vraiment bienvenue parce que ça fait une semaine que je cherche et j'arrive pas à trouver la solution. MERCI d'avance.
A voir également:
- Listes simplement chaînées
- Listes déroulantes excel - Guide
- Listes déroulantes en cascade excel - Guide
- Télécharger vidéo youtube simplement - Guide
- Remplacer un disque dur par un ssd simplement sans réinstaller windows - Guide
- Listes whatsapp - Guide
5 réponses
Salut
le problème, c'est que tu casses ta liste en supprimant p.
tu arrives à ton maillon de chaine (*p) où tu as la valeur à supprimer. il faut donc que tu supprimes ton maillon et que tu relies le maillon précédent avec le maillon suivant. Et là, dans ta façon de faire tu ne sais plus quel est le maillon précédent, ta chaine est mal reconstruite.
Fait aussi attention à bien prendre en compte les condtions de bord (si le premier maillon est supprimé, ou le dernier)
le problème, c'est que tu casses ta liste en supprimant p.
tu arrives à ton maillon de chaine (*p) où tu as la valeur à supprimer. il faut donc que tu supprimes ton maillon et que tu relies le maillon précédent avec le maillon suivant. Et là, dans ta façon de faire tu ne sais plus quel est le maillon précédent, ta chaine est mal reconstruite.
Fait aussi attention à bien prendre en compte les condtions de bord (si le premier maillon est supprimé, ou le dernier)
d'abord merci d'avoir répondu;
Oui je savais déjà avant la compilation que ma fonction n'allait pas donner le résultat escompté et que le problème vient en effet du fait qu'après suppression des 31, les éléments non supprimés ne sont plus reliés entre eux mais je voulais juste savoir si quelqu'un pouvait me donner la solution directe, lol le code C quoi!
Oui je savais déjà avant la compilation que ma fonction n'allait pas donner le résultat escompté et que le problème vient en effet du fait qu'après suppression des 31, les éléments non supprimés ne sont plus reliés entre eux mais je voulais juste savoir si quelqu'un pouvait me donner la solution directe, lol le code C quoi!
Salutations;
j'ai oublié de poster un message pour dire que la question est réglée :)
euuuuuuuhhhh j'ai résolu ça en utilisant malheureusement les listes doublement chaînées :( , j'ai essayé avec les listes simples mais je ne suis pas arrivé à chaîner les éléments entre eux après suppression (surtout ceux qui sont situés au milieu).
Merci Char Snipeur pour ton aide
j'ai oublié de poster un message pour dire que la question est réglée :)
euuuuuuuhhhh j'ai résolu ça en utilisant malheureusement les listes doublement chaînées :( , j'ai essayé avec les listes simples mais je ne suis pas arrivé à chaîner les éléments entre eux après suppression (surtout ceux qui sont situés au milieu).
Merci Char Snipeur pour ton aide
#include <stdio.h>
#include <stdlib.h>
typedef struct listeElement {
int val;
struct listeElement *prev;
struct listeElement *next;
}element;
typedef struct listeRepere {
size_t length;/
element *head;
element *tail;
}liste;
void initialisation(liste *p) {
p->length = 0;
p->head = NULL;
p->tail = NULL;
}
liste *Suppression(liste *p, int valeur) {
if(p != NULL) {
element *temp = p->head;
while(temp != NULL) {
if(temp->val == valeur) {
element *sup = temp;
temp = temp->next;
if(sup->next == NULL) {
p->tail = sup->prev;
p->tail->next = NULL;
}
else if(sup->prev == NULL) {
p->head = sup->next;
p->head->prev = NULL;
}
else {
sup->next->prev = sup->prev;
sup->prev->next = sup->next;
}
free(sup);
p->length--;
}
else {
temp = temp->next;
}
}
}
return p;
}
int main() {
liste *Mapile = NULL;
initialisation(Mapile);
Suppression(&Mapile);
return 0;
}
Comme tu as bien travaillé, je te montre une façon de faire (pas testé, donc peut être des bugs)
void sup_Multipl(pile *p, int valeur) {
pile* prec=p;
if(p->val==valeur)
{
p=p->next;
free( tmp);
sup_Multipl(p,valeur);
return;
}
while(p->next != NULL) {
if(p->next->val == valeur) {
prec= p->next;
p->next=prec->next;
free(prec);
}
else p = p->next;
}
} Je n'ai pas testé, mais ça devrait fonctionner. Sauf qu'il reste un problème, si ton premier élément vaut "valeur", alors tu perds le début de ta liste chainée, mieux vaut passer pile**p afin de modifier la valeur passé en argument.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
prec tu veux dire tmp, J'ai compris en tous cas ton raisonnement mais il semblerai que ça ne marche pas. même en utilisant pile **p.
ma liste contient 31 31 31 69 31 33 15 avec ta méthode tous est effacés sauf le dernier élément (15), j'ai modifié le else comme suit: p->next =(p->next)->next;
et cette fois ci à la compilation j'ai comme résultat 69 .
mais je vais essayé de réfléchir à ça
ma liste contient 31 31 31 69 31 33 15 avec ta méthode tous est effacés sauf le dernier élément (15), j'ai modifié le else comme suit: p->next =(p->next)->next;
et cette fois ci à la compilation j'ai comme résultat 69 .
mais je vais essayé de réfléchir à ça
Oui, en effet encore une erreur, j'ai fait un double raisonnement faux. En fait dans une liste chainée, il faut un debut et un pointeur pour la parcourir.
void sup_Multipl(pile **d, int valeur) {
pile* prec;
pile* p=*d;
if(p->val==valeur)
{
*d=p->next;
free( p);
sup_Multipl(d,valeur);
return;
}
while(p->next != NULL) {
if(p->next->val == valeur) {
prec= p->next;
p->next=prec->next;
free(prec);
}
else p = p->next;
}
} comme ça, ça devrait aller mieux.