TP6: Add ABR and tree n
[Algorithmic_C.git] / TP6 / arbres / ABR / ABR.c
CommitLineData
5f72f302
JB
1/*****************************************************************************/
2/* ABR : arbres binaires de recherche */
3/*****************************************************************************/
4
5#include <stdio.h>
6#include <stdlib.h>
7
8typedef int element;
9
10typedef struct noeud {
11 element valeur;
12 struct noeud *gauche;
13 struct noeud *droit;
14} NOEUD, *ABR;
15
16
17/* Creation d'un ABR vide */
18NOEUD *arbre_vide()
19{
20 return NULL;
21}
22
23
24/* Insertion/Ajout d'un nouvel element dans l'ABR */
25NOEUD *insere(NOEUD *p, element x)
26{
27 if(p == NULL)
28 {
29 p = (NOEUD *)malloc(sizeof(NOEUD));
30 p->valeur = x;
31 p->gauche = NULL;
32 p->droit = NULL;
33 }
34 else if (x == p->valeur) printf("%d est deja dans l'arbre\n",x);
35 else if (x < p->valeur) p->gauche = insere(p->gauche,x);
36 else p->droit = insere(p->droit,x);
37 return p;
38}
39
40
41/* Recherche d'un element dans l'ABR */
42int recherche(NOEUD *p, element x)
43{
44 if(p == NULL) return 0;
45 if(x == p->valeur) return 1;
46 if(x < p->valeur) return recherche(p->gauche,x);
47 else return recherche(p->droit,x);
48}
49
50
51/* Affichage du contenu de l'ABR en ordre croissant (par parcours profondeur infixe) */
52void affiche(NOEUD *p)
53{
54 if(p)
55 {
56 affiche(p->gauche);
57 printf("%d ",p->valeur);
58 affiche(p->droit);
59 }
60}
61
62
63/* Affichage de l'arbre (sous forme arborescente) */
64void affiche_arbre(NOEUD *p, int col)
65{
66 int i;
67 if(p)
68 {
69 affiche_arbre(p->droit,col+1);
70 for (i=0;i<col;i++) printf(" ");
71 printf("%d\n",p->valeur);
72 affiche_arbre(p->gauche,col+1);
73 }
74}
75
76
77/* Copie d'arbre (on cree physiquement le double de l'arbre de racine p) */
78NOEUD *copie_arbre(NOEUD *p)
79{
80 NOEUD *q;
81 if(p == NULL) return NULL;
82 else
83 {
84 q = (NOEUD *)malloc(sizeof(NOEUD));
85 q->valeur = p->valeur;
86 q->gauche = copie_arbre(p->gauche);
87 q->droit = copie_arbre(p->droit);
88 return q;
89 }
90}
91
92
93/* Destruction de l'arbre de racine p en recuperant la place occupee (free) par chacun des noeuds */
94NOEUD *detruis_arbre(NOEUD *p)
95{
96 if(p == NULL) return p;
97 else
98 {
99 p->gauche = detruis_arbre(p->gauche);
100 p->droit = detruis_arbre(p->droit);
101 free(p);
102 p = NULL;
103 return p;
104 }
105}
106
107
108/* Maximum d'un sous-arbre de racine p (i.e., le noeud le plus a droite) */
109NOEUD *max(NOEUD *p, NOEUD *r)
110{
111 NOEUD *q;
112 if (r->droit == NULL)
113 {
114 p->valeur = r->valeur;
115 q = r; /* q : l'element a supprimer par free */
116 r = r->gauche;
117 free(q);
118 }
119 else r->droit = max(p,r->droit);
120 return r;
121}
122
123
124/* Suppression du noeud de valeur x dans l'arbre de racine p.
125 Suppression d'un noeud interne : la valeur du noeud a supprimer est
126 remplacee par celle du noeud le plus a droite de son sous-arbre gauche */
127NOEUD *supprime(NOEUD *p, element x)
128{
129 NOEUD *q;
130 if(p == NULL) printf("%d n'est pas dans l'arbre\n",x);
131 else
132 if(x == p->valeur)
133 { /* suppression de p */
134 if (p->droit == NULL) {q = p ; p = p->gauche; free(q); }
135 else if (p->gauche == NULL) {q = p ; p = p->droit; free (q); }
136 else p-> gauche = max(p,p->gauche);
137 }
138 else if (x < p->valeur) p->gauche = supprime(p->gauche,x);
139 else p->droit = supprime(p->droit,x);
140 return p;
141}
142
143
144/* Chargement d'un arbre depuis un fichier */
145NOEUD *charge(NOEUD *p, FILE *fich)
146{
147 if (p) {p = (NOEUD *)malloc(sizeof(NOEUD));
148 fread(p,sizeof(NOEUD),1,fich);
149 p->gauche = charge(p->gauche,fich);
150 p->droit = charge(p->droit,fich);
151 }
152 return p;
153}
154
155
156/* Sauvegarde d'un arbre dans un fichier */
157NOEUD *sauve(NOEUD *p, FILE *fich)
158{
159 if (p) {fwrite(p,sizeof(NOEUD),1,fich);
160 p->gauche = sauve(p->gauche,fich);
161 p->droit = sauve(p->droit,fich);
162 }
163 return p;
164}
165
166
167
168
169/*****************************************************************************/
170main()
171{
172 NOEUD *abr; /* on peut travailler sur 3 arbres */
173 NOEUD *abr2 = NULL;
174 char c;
175 int i, j;
176 element x;
177 char nom_fich[20];
178 FILE *fich;
179
180printf("Commandes (une lettre) possibles : v arbre_vide ; r rechercher ; i inserer ; c copier ; d detruire ; a afficher contenu ; A affiche arborescence ; s supprimer ; C charger ; S sauvegarder)\n");
181
182 do {
183 printf("Commande ? ");
184 c = getchar();
185 switch(c)
186 {
187 case 'v' : abr = arbre_vide(); break;
188
189 case 'r' : printf("indiquer l'element a rechercher : ");
190 scanf("%d",&x);
191 if (recherche(abr,x) == 0) printf("pas trouve\n");
192 else printf("trouve\n");
193 break;
194
195 case 'i' : printf("indiquer l'element a inserer : ");
196 scanf("%d",&x);
197 abr = insere(abr,x);
198 break;
199
200 case 'c' : abr2 = copie_arbre(abr);
201 break;
202
203 case 'd' : abr = detruis_arbre(abr);
204 if(abr2) abr2 = detruis_arbre(abr2);
205 break;
206
207 case 'a' : affiche(abr);
208 if(abr2) {printf("\nLa copie : \n");
209 affiche(abr2);};
210 break;
211
212 case 'A' : affiche_arbre(abr,1);
213 if(abr2) {printf("\nLa copie : \n");
214 affiche_arbre(abr2,1);};
215 break;
216
217 case 's' : printf("indiquer l'element a supprimer : ");
218 scanf("%d",&x);
219 abr = supprime(abr,x);
220 break;
221
222 case 'C' : printf("indiquer le nom de fichier pour le chargement : ");
223 scanf("%s",nom_fich);
224 if ((fich = fopen(nom_fich,"rb")) != NULL)
225 {abr = (NOEUD *)malloc(sizeof(NOEUD));
226 abr = charge(abr,fich);
227 fclose(fich);
228 };
229 break;
230
231 case 'S' : printf("indiquer le nom de fichier pour la sauvegarde : ");
232 scanf("%s",nom_fich);
233 if ((fich = fopen(nom_fich,"wb")) != NULL)
234 {abr = sauve(abr,fich);
235 abr = NULL;
236 fclose(fich);
237 };
238 break;
239
240 case 'q' : exit(0);
241 }
242 printf("\n"); c = getchar();
243 }
244 while (1);
245}
246
247
248/* Trace d'execution **************************************
249Commandes (une lettre) possibles : v arbre_vide ; r rechercher ; i inserer ; c copier ; d detruire ; a afficher contenu ; A affiche arborescence ; s supprimer ; C charger ; S sauvegarder)
250Commande ? v
251
252Commande ? i
253indiquer l'element a inserer : 2
254
255Commande ? i
256indiquer l'element a inserer : 6
257
258Commande ? i
259indiquer l'element a inserer : 4
260
261Commande ? i
262indiquer l'element a inserer : 5
263
264Commande ? i
265indiquer l'element a inserer : 1
266
267Commande ? i
268indiquer l'element a inserer : 0
269
270Commande ? a
2710 1 2 4 5 6
272Commande ? A
273 6
274 5
275 4
276 2
277 1
278 0
279
280Commande ? r
281indiquer l'element a rechercher : 4
282trouve
283
284Commande ? r
285indiquer l'element a rechercher : 3
286pas trouve
287
288Commande ? s
289indiquer l'element a supprimer : 4
290
291Commande ? a
2920 1 2 5 6
293Commande ? A
294 6
295 5
296 2
297 1
298 0
299
300Commande ? S
301indiquer le nom de fichier pour la sauvegarde : sauv.txt
302
303Commande ? C
304indiquer le nom de fichier pour le chargement : sauv.txt
305
306Commande ? a
3070 1 2 5 6
308Commande ? A
309 6
310 5
311 2
312 1
313 0
314
315Commande ? q
316
317******************************************************************************/