L'avantage de cette structure de données est que l'on peut facilement ajouter des éléments au milieu. Il n'est pas nécessaire de décaler toute la suite comme dans l'exemple de la bibliothèque du chapitre précédent. Mais (il y a toujours un mais) on ne peut pas directement accéder à une case donnée… tout simplement parce qu'on ne sait pas où elle se trouve dans la mémoire. . On est obligé de suivre toute la chaîne des éléments. Pour aller à la huitième case, il faut aller à la première case, suivre le pointeur jusqu'à la deuxième, suivre le pointeur jusqu'à la troisième et ainsi de suite jusqu'à la huitième. C'est donc très coûteux.
Je ne saisis pas la différence de difficulté algorithmique entre le fait d'ajouter des éléments au milieu et le fait d'accéder à une case donnée.
Est-ce parce que l'élément du milieu est situé à la position n/2 (donc on connaît la position) ?
Dans un vector, les elements sont contingues en memoire, tu peux aller directement a n'importe quel element en memoire (c'est a dire trouver son adresse memoire) en calculant a partir de l'adresse memoire du premier element du tableau.
Avec une liste chainee, les elements sont n'importe où en memoire et il n'est pas possible de calculer l'adresse. Il faut partir du premier element et aller a l'element suivant jusqu'a trouver l'element recherché.
Pour inserer un element dans un vector, cela veut dire qu'il faut copier tous les elements qui se trouvent apres l'element inseré. Dans la cas d'une liste, il faut juste changer les pointeurs, il n'est pas necessaire de copier.
En pratique, ce n'est pas vrai. L'insertion (meme avec les copies) dans un vector est souvent plus rapide qu'une insertion dans une liste. Utilises des std::vector par defaut.
Tu devrais aussi suivre un autre cours, un qui t'apprendrait à ne pas utiliser des listes pour récupérer des éléments à la manière d'un simple tableau de données par exemple.
Dans un std::vector, les éléments sont placé les uns à la suite des autres, raison pour laquelle nous pouvons accéder à un élément de cette manière :
vec[n];
Un std::liste, lui, n'est pas ordonné à la façon d'un std::vector. On ne l'utilisera d'ailleurs pas pour récupérer des éléments à des indexe précis, comme on le ferait pour un tableau. Il y a une façon d'accéder à un élément "précis", mais c'est coûteux (puisque "aléatoire") :
std::list<T> MyList;
...
std::list<T>::iterator it = MyList.begin();
std::advance(it, n);
L'itérateur it pointe désormais l'élément situé à la position n :
T item = *it;
Mais tu as des chances de tomber sur un autre élément que celui attendu. En effet, la liste enregistre ses données dynamiquement (pas de mémoire pré allouée) sur le tas.
- Edité par vanaur 14 août 2018 à 12:30:09
Le meilleur moyen de prédire l'avenir, c'est de l'inventer | N'oubliez pas [résolu] et +1 | Excusez mon ôrtograffe, j'essaie de l'améliorer...
C'est que le cours est rédigé de façon épouvantable, avec un manque de précision que ne remarquent pas les débutants, mais dont ils sont vite les victimes.
Si on prend par exemple (pour les listes chainées) "on ne peut pas directement accéder à une case donnée… parce qu'on ne sait pas où elle se trouve dans la mémoire."
Qu'est ce que ça veut dire "une case donnée" ? Si la case est "donnée" par un pointeur sur la cellule qui contient la valeur, on sait parfaitement où elle est. Si on dit "la première", on sait aussi.
Ce qu'il fallait dire, c'est qu'on n'a pas accès directement à autre chose qu'au premier élément de la liste. Ensuite, si on cherche une case par son contenu, ou par son indice (0 pour la première, 1 pour la seconde, etc), il faudra parcourir la chaine, d'élément en élément. Et ça prendra un temps proportionnel à la "distance" où se trouve ce qu'on cherche.
Dans un tableau, par contre, l'accès par indice est direct. Mais pas par contenu.
Bonjour j'ai un petit souci avec mon code source en C je veux créer une méthode pour insérer des étudiants et calculer par la suite leur moyenne mais je arrive a afficher les étudiant saisis mais je n arrive pas a afficher les moyennes par la suites .Aidez moi svp plait .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// Déclarations des types pour la structure note
typedef struct Note
{ int coef;
int note;
int moy;
struct Note* suivant ;
} Note;
// Déclarations des types pour la structure etudiant
typedef struct Etudiant
{
struct Etudiant*prec ;
char numero[10];
char nom[30];
char prenom[10];
int moy;
struct Note*eval ;
struct Etudiant*suivant ;
} Etudiant;
// Déclarations des pointeurs etudiant et pointeur note
typedef Etudiant*Pe;
typedef Note*Pn;
// Variables
Pe p1;
Pe p ;
Pn p2;
Pe petu;
Pn pnote;
Pe tete;
void Inserer_Etudiant(Pe tete)
{
int rep=0;
int dec=1;
int rep1=0;
int dec1=1;
///Creation du premier element de liste Etudiant-----------
(petu) = malloc(sizeof(Etudiant));
printf("Saisissez le numero de l'etudiant : ");
gets(petu->numero);
printf("Saisissez le nom de l'etudiant : ");
gets(petu->nom);
printf("Saisissez le prenom de l'etudiant : ");
gets(petu->prenom);
// Insertion de notes
printf("Vouliez vous ajouter une nouvelle note - Repondez par (0/1)");
scanf("%i",&rep1);
dec1 = rep1;
/// Saisit de la premiere note ou rien ------------------------------------------
if (dec1==0)
{
petu->eval= NULL;
}
else // On saisit la premiere note ...
{
(pnote) = malloc(sizeof(Note));
printf("Saisissez la note de l'etudiant : ");
scanf("%d",&pnote->note);
printf("Saisissez le coefficient de cette note : ");
scanf("%d",&pnote->coef);
petu->eval =pnote ;
p2 = pnote ;
}
///Saisir de la deuxienne note ----
if(dec1 != 0)
{
dec1 ==0;
//Saisir deuxiemem note
printf("Vouliez vous ajouter une nouvelle note - Repondez par (0/1)");
scanf("%i",&rep1);
dec1 = rep1;
if(dec==1)
{
(pnote) = malloc(sizeof(Note));
p2->suivant = pnote ;
printf("Saisissez la note de l'etudiant : ");
scanf("%d",&pnote->note);
printf("Saisissez le coefficient de cette note : ");
scanf("%d",&pnote->coef);
p2 = pnote ;
}
}
/// FIn de saisie de note ------
pnote->suivant = NULL;
/// FIn de la saisie etudiant
tete = petu ;
p1 = petu;
///-------------------------------------------------------------------------------------
///Creation du deuxieme element de liste Etudiant-----------
printf("Vouliez vous ajouter un nouveau etudiant - Repondez par (0/1)");
scanf("%i",&rep);
dec = rep;
if (dec != 0 )
{
(petu) = malloc(sizeof(Etudiant));
p1->suivant = petu ;
printf("Saisissez le numero de l'etudiant : ");
gets(petu->numero);
printf("Saisissez le nom de l'etudiant : ");
gets(petu->nom);
printf("Saisissez le prenom de l'etudiant : ");
gets(petu->prenom);
// Insertion de notes
printf("Vouliez vous ajouter une nouvelle note - Repondez par (0/1)");
scanf("%i",&rep1);
dec1 = rep1;
/// Saisit de la premiere note ou rien ------------------------------------------
if (dec1==0)
{
petu->eval= NULL;
}
else // On saisit la premiere note ...
{
(pnote) = malloc(sizeof(Note));
printf("Saisissez la note de l'etudiant : ");
scanf("%d",&pnote->note);
printf("Saisissez le coefficient de cette note : ");
scanf("%d",&pnote->coef);
petu->eval =pnote ;
p2 = pnote ;
}
///Saisir de la deuxienne note ----
if(dec1 != 0)
{
dec1 ==0;
//Saisir deuxiemem note
printf("Vouliez vous ajouter une nouvelle note - Repondez par (0/1)");
scanf("%i",&rep1);
dec1 = rep1;
if(dec==1)
{
(pnote) = malloc(sizeof(Note));
p2->suivant = pnote ;
printf("Saisissez la note de l'etudiant : ");
scanf("%d",&pnote->note);
printf("Saisissez le coefficient de cette note : ");
scanf("%d",&pnote->coef);
p2 = pnote ;
}
}
}
/// FIn de saisie de note ------
pnote->suivant = NULL;
/// FIn de la saisie etudiant
p1 = petu ;
/// Fin de saisie etudiant
petu->suivant = NULL ;
/// Affichage de liste etudiant & note ---------
// AFFICHER TOUS LES ENREGSTEMENTS
p1 = tete;
printf("LA LISTE SAISIE EST : \n");
printf("\n");
while (p1 != NULL)
{
p2 = p1->eval;
printf("Numero : %s", p1->numero);
printf("\n");
printf("Nom : %s", p1->nom);
printf("\n");
printf("Prenom : %s", p1->prenom);
//printf("\n");
//printf("Moyenne : %2d", p1->moy);
printf("\n");
if (petu->eval != NULL )
{
pnote=p1->eval;
p2 = pnote;
printf("Notes : %d (coef : %d )",p2->note,p2->coef);
p2 = pnote->suivant;
while (p2 !=NULL)
{
printf(", %d (coef : %d )",p2->note,p2->coef);
pnote=p2;
p2= pnote->suivant;
};
printf("\n");
};
p1 = p1->suivant;
printf("================================================================");
printf("\n");
}
printf("\n");
printf("FIN DE LISTE : \n");
printf("\n");
/// Fin de affichage liste
/// AFFICHER FINISH
///Variables
int totcoef;
int totnote ;
/// Debut
petu = tete ;
while (petu != NULL)
{
totcoef = 0 ;
totnote = 0;
pnote = petu->eval ;
while (pnote != NULL)
{
totcoef = totcoef + pnote->coef ;
totnote = totnote + pnote->note * pnote->coef ;
p2 = pnote ;
pnote =p2->suivant ;
}
if ( petu->eval != NULL)
{
petu->moy = totnote / totcoef ;
}
}
// AFFICHER TOUS LES ENREGSTEMENTS
p1 = tete;
printf("LA LISTE SAISIE EST : \n");
printf("\n");
while (p1 != NULL)
{
p2 = p1->eval;
printf("Numero : %s", p1->numero);
printf("\n");
printf("Nom : %s", p1->nom);
printf("\n");
printf("Prenom : %s", p1->prenom);
printf("\n");
printf("Moyenne : %i", p1->moy);
printf("\n");
p1 = p1->suivant;
printf("================================================================");
printf("\n");
}
printf("\n");
printf("FIN DE LISTE : \n");
/// Fin de affichage liste
/// FIn de fonction
}
void Calcul_moy(Pe tete)
{
///Variables
int totcoef;
float totnote ;
/// Debut
petu = tete ;
while (petu != NULL)
{
totcoef = 0 ;
totnote = 0;
pnote = petu ->eval ;
while (pnote != NULL)
{
totcoef = totcoef + pnote->coef ;
totnote = totnote + pnote->note*pnote->coef ;
p2 = pnote ;
pnote =p2->suivant ;
}
if ( petu->eval != NULL)
{
petu->moy = totnote / totcoef ;
}
}
// AFFICHER TOUS LES ENREGSTEMENTS
p1 = tete;
printf("LA LISTE SAISIE EST : \n");
printf("\n");
while (p1 != NULL)
{
p2 = p1->eval;
printf("Numero : %s", p1->numero);
printf("\n");
printf("Nom : %s", p1->nom);
printf("\n");
printf("Prenom : %s", p1->prenom);
//printf("\n");
//printf("Moyenne : %2d", p1->moy);
printf("\n");
if (petu->eval != NULL )
{
pnote=p1->eval;
p2 = pnote;
printf("Notes : %d (coef : %d )",p2->note,p2->coef);
p2 = pnote->suivant;
while (p2 !=NULL)
{
printf(", %d (coef : %d )",p2->note,p2->coef);
pnote=p2;
p2= pnote->suivant;
};
printf("\n");
};
p1 = p1->suivant;
printf("================================================================");
printf("\n");
}
printf("\n");
printf("FIN DE LISTE : \n");
/// Fin de affichage liste
}
int main()
{
printf("Hello world!\n");
tete=NULL;
Inserer_Etudiant(tete);
Calcul_moy(tete) ;
}
Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.
Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre. En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.
Au lieu de déterrer un sujet il est préférable :
soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
soit de créer un nouveau sujet décrivant votre propre contexte
ne pas répondre à un déterrage et le signaler à la modération
Discord NaN. Mon site.
Le meilleur moyen de prédire l'avenir, c'est de l'inventer | N'oubliez pas [résolu] et +1 | Excusez mon ôrtograffe, j'essaie de l'améliorer...
Pas d'aide concernant le code par MP, le forum est là pour ça :)