Vous êtes sur la page 1sur 5

Université Mustapha Stambouli - Mascara - 14/01/2019

Faculté des Sciences Exactes Durée :1 h 30


Département informatique 2ème Année LMD Informatique

Examen Algorithmique et Structures de Données


Exercice 1 (6 pts)

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.

1. Écrirez un algorithme permettant de calculer cette somme. (1 pt)


2. Calculez la complexité de votre algorithme en meilleur cas.(1 pt)

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.

3. Définir la structure de données représentant cette liste. (0.5 pt)


4. En utilisant le langage C, écrivez une fonction Liste getListeMCC(int m [n][n]) qui permet de
concevoir le liste l représentant une matrice creuse carrée de taille n x n. (1.5 pt)
5. Soit l une liste représentant un matrice creuse carrée, écrivez un algorithme qui calcule la somme
des éléments de cette matrice à partir de la liste l. (1 pts)
6. Calculez la complexité de votre algorithme en meilleur cas en le comparant avec l'algorithme de
la première question. (1 pt)

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);}

void supprimer(int x, arbre * A){


int maxi;
arbre temp;
if( (*A)!=NULL)
if (x<(*A)->val) supprimer( x, &(*A)->g);
else if (x>(*A)->val) supprimer( x, &(*A)->d);
else
if ((*A)->g==NULL) (*A)=(*A)->d;
else if ((*A)->d==NULL) (*A)=(*A)->g;
else {
supmax(&(*A)->g,&maxi);
(*A)->val=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));}
}

Vous aimerez peut-être aussi