Vous êtes sur la page 1sur 9

Université Abou Bekr Belkaid – Tlemcen Année Universitaire 2021-2022

Faculté des Sciences L2 Licence Informatique UEI-72


Département d’Informatique Durée : 1H30 – M.BENAZZOUZ
Algorithmique et Structures de Données
EXAMEN FINAL

Exercice 1 : (5 pts).
On dispose d’un tableau T (liste contigüe) de taille N contenant des éléments entiers. On nous demande
d’inverser les éléments de T (sans utiliser un autre tableau).
1. Écrire une fonction itérative.
2. Écrire une fonction récursive ( ainsi que son premier appel ).

0 1 2 3 4 5

T: 5 8 1 9 12 4

0 1 2 3 4 5

après inversion T : 4 12 9 1 8 5

Exercice 2 : (8 pts).

Étant donné une liste chainée d’entiers L (non vide) :


L

val nxt

On souhaite créer deux sous-listes L1 et L2, tel que L1 contient les valeurs de la première moitié
de L, et L2 contient les valeurs restantes de l’autre moitié. La liste initiale L sera conservée et
l’ordre des éléments doit être respecté dans L1 et L2.

1. Écrire une fonction « moitié-1 » permettant de créer une liste chainée L1 dont les
éléments sont identiques à la première moitié de L.
2. Écrire une fonction « moitié-2 » permettant de créer une liste chainée L2 dont les
éléments sont identiques à la deuxième moitié de L.
3. Écrire une fonction « verif » permettant de vérifier que la liste initiale L est l’union de
L1 et L2.

L 7 2 8 5 1 ×

L1 7 2 8 ×

L2 5 1 ×
Page 1 / 2
Exercice 3 : (7 pts).

1. Implémenter un algorithme pour la recherche d’une clé (valeur) v dans un arbre binaire
de recherche b ; l’algorithme retourne 1 si v figure dans b et 0 sinon.

o Itérative.
o Récursive.

2. Construire un arbre AVL à partir des clés :

25 15 40 20 30 18 28
Examiner la propriété de l’équilibre après chaque ajout.

Page 2 / 2
Algorithmique - Corrigé
Exercice 1:

Solution Itérative Solution Récursive 1

void Inverser_Tab1(int n, int t[n])


void Rev_Array(int T[], int start, int end) {
{ if (n>1) {
int temp; int tmp=t[n-1];
while (start < end) t[n-1]=t[0];
{ t[0]=tmp;
temp = T[start]; Inverser_Tab1 (n-2,t+1);
T[start] = T[end]; }
T[end] = temp; }
start++;
end--;
}
}
Appel - 1 : Inverser_Tab1(N,T);

Solution Récursive 2 Solution Récursive 3


void Inverser_Tab2(int T[], int start,int end) { void Inverser_Tab3(int *t,int *n,int *m){

int temp; int c;

if (start < end) { if ( n< m){

temp = T[start]; c = *n;

T[start] = T[end]; *n = *m;

T[end] = temp; *m = c;

Inverser_Tab2(T,start+1,end-1); Inverser_Tab3(t, n+1, m-1);

} }

} }

Appel -2 : Inverser_Tab2(T,0,N-1); Appel - 3 : Inverser_Tab2(T,T,T+N-1);


Exercice 2 :

Calculer le nombre d’éléments d’une liste chainée


int taille(Liste L){
int t = 1;
Liste courant = L;
while(courant->nxt !=NULL){
t++;
courant = courant->nxt;
}
return t;
}

Fonction pour ajouter un élément en fin de liste


Liste Ajouter_fin(Liste L1,Liste L)
{ Liste d;
L->nxt=NULL;
if(L1==NULL) return L;
d=L1;
while(L1->nxt!=NULL)
L1=L1->nxt;
L1->nxt=L;
return d;
}

Créer une liste chainée L1 dont les éléments sont identiques à la première moitié de L.

Liste moitie1(Liste L)
{
Liste m ;
int Tl=taille(L), m1 ;
if (Tl%2==0) m1=Tl/2;
else m1=Tl/2 + 1;
if(m1==0) return NULL;
Liste L1=NULL,P,d;
m= (Liste) malloc(sizeof(cellule));
m->val = L->val;
L1= Ajouter_fin( L1,m);
L=L->nxt;
for(int i=1;i<m1;i++)
{
m= (Liste) malloc(sizeof(cellule));
m->val = L->val;
L1= Ajouter_fin( L1,m);
L=L->nxt;
}

return L1;
}
Écrire une fonction « moitié-2 » permettant de créer une liste chainée L2 dont les éléments
sont identiques à la deuxième moitié de L.

Liste moitie2(Liste L)
{
Liste m;

int Tl=taille(L), m1,m2 ;


if (Tl%2==0) m1=Tl/2;
else m1=Tl/2 + 1;
int m2=Tl-m1;
if(m2==0) return NULL;
for(int i=0;i<Tl/2;i++) L=L->nxt;
Liste L2=NULL,P,d;
m= (Liste) malloc(sizeof(cellule));
m->val = L->val;
L2= Ajouter_fin( L2,m);
L=L->nxt;
for(int i=1;i<m2;i++)
{
m= (Liste) malloc(sizeof(cellule));
m->val = L->val;
L2= Ajouter_fin( L2,m);
L=L->nxt;
}

return L2;
}

Écrire une fonction « verif » permettant de vérifier que la liste initiale L est l’union de L1 et L2.

int verif(Liste L, Liste L1, Liste L2)


{
int Tl=taille(L);
int m1=Tl/2;
int m2=Tl-m1;
for(int i=0;i<m1;i++)
{
if(L->val!=L1->val) return 0;
L=L->nxt; L1=L1->nxt;
}
for(int i=0;i<m2;i++)
{
if(L->val!=L2->val) return 0;
L=L->nxt; L2=L2->nxt;
}
return 1;
}
Exercice 3 :
Version itérative
Algorithme rechercher (ABR b, Valeur v) : retourne 1 ou 0
Début
Tant que (b ≠ vide) et (v ≠ b.val )
Si (v < b.val) Alors b = b.fg
Sinon b = b.fd
Finsi
Fin tq
Si (b=vide) Alors retourner 0
Sinon retourner 1
Finsi

Fin

Version récursive
Algorithme Rechercher (ABR b, Valeur v) : retourne 1 ou 0
Début
Si (b=vide) Alors retourner 0
Sinon
Si (v = b.val) lors retourner 1
Sinon
Si (v < b.val) Alors retourner Rechercher ( b, v.fg)
Sinon retourner Rechercher ( b, v.fd)
Fsi
Fsi
Fsi
Fin
Construction AVL :
Annexe EXO1

#include<stdio.h>

void Saisir_Tab(int t[], int n, int i){


if ((n==0) || (i==n))
return;
else{
printf("\tT[%d]=", i);
scanf("%d" ,&t[i]);
Saisir_Tab(t,n,++i);
}
}

void Afficher_Tab(int t[],int n){


if(n>=0){
Afficher_Tab(t,n-1);
printf("\t%d ",t[n]);
}
}

void Inverser_Tab1(int Tab[], int start,int end) {


int temp;
if (start < end) {
temp = Tab[start];
Tab[start] = Tab[end];
Tab[end] = temp;

Inverser_Tab1(Tab,start+1,end-1);
}
}

void Inverser_Tab2(int *t,int *n,int *m){


int c;
if ( n< m){
c = *n;
*n = *m;
*m = c;
Inverser_Tab2(t, n+1, m-1);
}
}

void Inverser_Tab3(int n, int t[n]){


if (n>1){
int tmp=t[n-1]; // t[0]^=t[n-1];
t[n-1]=t[0]; // t[n-1]^=t[0];
t[0]=tmp; // t[0]^=t[n-1];
Inverser_Tab3(n-2,t+1);
}
}
int main(){
int T[10];
int N;
printf("\n\tEntrez la taille du Tableau : ");
scanf("%d",&N);
printf("\n\tEntrez les elements du Tableau: \n");
Saisir_Tab(T,N,0);
printf("\n\tTableau Avant Inversion : \n");
Afficher_Tab(T,N-1);

Inverser_Tab1(T,0,N-1);
printf("\n\tTableau Apres Inversion 1 : \n");
Afficher_Tab(T,N-1);

Inverser_Tab2(T,T,T+N-1);
printf("\n\tTableau Apres Inversion 2 : \n");
Afficher_Tab(T,N-1);

Inverser_Tab3(N,T);
printf("\n\tTableau Apres Inversion 3 : \n");
Afficher_Tab(T,N-1);
return 0;
}

Vous aimerez peut-être aussi