Académique Documents
Professionnel Documents
Culture Documents
On considère des « matrices creuses carrées», c'est-à-dire des matrices d’entiers contenant environ 90%
d’éléments nuls. Le problème considéré consiste à calculer la somme des éléments d’une matrice creuse.
Pour diminuer la complexité spatiale de ce problème, on propose de présenter cette matrice par une liste
simplement chaînée dans laquelle on ne s’intéresse qu’aux éléments de la matrice qui ne sont pas nuls.
Chaque cellule de cette liste contient un triplet (i, j, val) correspondant à l’indice de ligne, l’indice de
colonne, et la valeur d’un élément non nul.
Exercice 2 (7 pts)
Soit l une liste doublement chaînée contenant des entiers triés par ordre croissant.
1. Écrirez une fonction inserer(int x, liste *l) qui insert une valeur x dans la liste l. le résultat est
toujours une liste triée. (1 pt)
Nous voulons disposer d'un opérateur ABSListe, qui transforme toutes les valeurs représentées dans la
liste l en valeurs absolues en gardant toujours l'ordre croissant. Pour cela, on propose deux solutions
possibles : soit on conserve le chaînage entre les cellules en modifiant uniquement les valeurs qui se
trouvent dans les cellules ; soit en concevant la valeur val de chaque cellule en modifiant éventuellement
les deux pointeurs suivant et précédent (voir l'exemple dans la figure ci-dessous).
Liste L
Solution 1
Solution 2
1
2. Écrivez une fonction qui implémente la solution 1. (3 pts)
3. Écrivez une fonction qui implémente la solution 2. (3 pts)
Exercice 3 (7 pts)
Soit un arbre binaire de recherche étiqueté par un ensemble d'éléments de type entier (y compris des
valeurs négatives) vérifiant la propriété suivante : Pour tout nœud < , , >, les éléments
apparaissant dans le sous-arbre gauche sont inférieures ou égaux à la valeur de l'élément ; et celles
du sous-arbre droit sont strictement supérieurs.
1. Écrivez une fonction ajouterFeuillle (int val, arbre * A) permettant l'adjonction d'un nœud
< , φ , φ > (avec val un entier signé et φ représente un arbre binaire de recherche vide), tel
que le nouveau nœud est inséré dans l'ensemble des feuilles de l'arbre binaire de recherche .
(1.5 pt)
2. Écrivez une procédure supprimer (int val, arbre * A) qui supprime le premier nœud de l'arbre A
contenant la valeur val. (2.5 pts)
3. On souhaite disposer d'une opération SépareArbre sur un arbre binaire de recherche qui
supprime toutes les étiquettes négatives de l'arbre A pour les conservées dans un autre arbre
binaire de recherche B.
A A B
SépareArbre
Écrivez une procédure itérative SépareArbre (arbre * A, arbre * B) qui implémente l'opérateur
SépareArbre. (3 pts)
2
Corrigé
Exercice 1
Question 1:
int sommeM(int mc[n][n]){
int s=0;
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
s+=mc[i][j];
return s;
}
Question 2:
complexité en meilleur cas: O(n²)
Question 3:
typedef struct cellule {
int Info;
int i;
int j;
struct celluleS *suivant ;} cellule;
typedef struct celluleS *liste;
Question 4:
void getM(int m[n][n],liste * L){
liste p;
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if(m[i][j]){
p= malloc (sizeof(celluleS));
p->Info=x;
p->i=i;
p->j=j;
p->suivant=*L;
*L=p;}
}
Question 5:
int somMCliste(liste L){
int s=0;
while (L!=NULL){
s+=L->Info;
L=L->suivant;
}
return s;
}
Question 6:
Complexité en meilleur cas est 0 dans le cas où la liste est vide
3
Exercice 2
Question 1:
void inserer(int x, listeD *l){
listeD p;
listeD temp;
p= malloc (sizeof(Cellule));
p->Info=x;
p->precedent=p->suivant=NULL;
if (*l== NULL) *l=p;
else if (x<= (*l)->Info) {
p->suivant=*l;
(*l)->precedent=p;
*l=p;}
else { temp=*l;
while (temp->suivant!=NULL && x>temp->suivant->Info )
temp=temp->suivant;
p->suivant=temp->suivant;
p->precedent=temp;
if(temp->suivant!=NULL) temp->suivant->precedent=p;
temp->suivant=p; }
}
Question 2:
void ABSSolution1(listeD *l){
int temp;
listeD pointeur;
if(*l!=NULL)
while ((*l)->Info<0){
temp=-1 * (*l)->Info;
pointeur=(*l);
while (pointeur->suivant !=NULL && pointeur->suivant->Info<temp ){
pointeur->Info=pointeur->suivant->Info;
pointeur=pointeur->suivant;
}
pointeur->Info=temp;
}
}
Question 3:
void ABSSolution2(listeD *l){
listeD temp, p;
while(*l!=NULL && (*l)->Info<0){
temp=*l;
temp->Info=-1 * (*l)->Info;
*l=(*l)->suivant;
(*l)->precedent=NULL;
temp->suivant=NULL;
p=(*l);
while (p->suivant!=NULL && temp->Info > p->suivant->Info ) p=p->suivant;
temp->suivant=p->suivant;
temp->precedent=p;
if(p->suivant!=NULL) p->suivant->precedent=temp;
p->suivant=temp; } }
4
Exercice 3
Question 1:
void ajouterFeuille (int x, arbre *A){
if((*A)==NULL) *A=creernoeud(x);
else if(x<= (*A)->val) ajouterFeuille (x, &(*A)->g);
else ajouterFeuille (x, &(*A)->d);
}
Question 2:
arbre supmax(arbre *A, int * maxi){
arbre temp;
if((*A)->d==NULL) {
*maxi=(*A)->val;
temp=(*A);
(*A)=(*A)->g;
return temp;
else supmax( &(*A)->d, maxi);}
Question 3:
void SeparArbre(arbre *a, arbre *b){
PILE p,p2;
p=p2=NULL;
arbre racine=*a;
while (racine!=NULL || (p!=NULL)) {
while (racine!=NULL){
if(racine->val<0)
empiler(racine,&p2);
empiler(racine,&p);
racine=racine->g;
}
racine=depiler (&p);
racine=racine->d; }
while ( p2!=NULL){
racine=depiler (&p2);
supprimer(racine->val, &(*a));
ajouterFeuille (racine->val, &(*b));}
}