TP6: Fix to the n ary tree.
[Algorithmic_C.git] / TP6 / arbres / arbre_n_aire / arbre_n_aire.c
... / ...
CommitLineData
1/*****************************************************************************/
2/* arbre_n_aire.c */
3/* Representation d'un ensemble de mots sous forme d'arbre n-aire */
4/*****************************************************************************/
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <stdbool.h>
10
11/* nombre de caracteres max dans un mot */
12#define N 30
13
14typedef struct noeud {
15 char lettre;
16 struct noeud *fils;
17 struct noeud *frere;
18} NOEUD;
19
20/* Recherche d'un mot dans l'arbre *****************************************/
21bool recherche(NOEUD * p, char *mot, int i)
22{
23 if (p == NULL)
24 return false;
25 if (mot[i] == p->lettre) {
26 if (mot[i] == '\0') {
27 return true;
28 } else {
29 return recherche(p->fils, mot, i + 1);
30 }
31 } else {
32 if (p->lettre > mot[i]) {
33 return false;
34 } else {
35 return recherche(p->frere, mot, i);
36 }
37 }
38}
39
40/* Creation d'une fin de mot (liste chainee suivant le lien fils) **********/
41NOEUD *insere_fin(char *mot, int i)
42{
43 /* i est l'indice de la lettre courante dans le mot */
44 printf("insere_fin %c, %i\n", mot[i], i);
45 NOEUD *p = (NOEUD *) malloc(sizeof(NOEUD));
46 if (p == NULL)
47 exit(-1);
48 p->lettre = mot[i];
49 p->fils = NULL;
50 p->frere = NULL;
51 if (mot[i])
52 p->fils = insere_fin(mot, i + 1);
53 return p;
54}
55
56/* Insertion d'un mot dans l'arbre ******************************************/
57/* (on respecte l'ordre lexicographique des freres)**************************/
58NOEUD *insere(NOEUD * p, char *mot, int i)
59{
60 /* i est l'indice de la lettre courante dans le mot */
61 if (p == NULL) {
62 return insere_fin(mot, i);
63 } else if (p->lettre == mot[i]) {
64 if (mot[i] != '\0') {
65 p->fils = insere(p->fils, mot, i + 1);
66 } else {
67 printf("The word is already here\n");
68 }
69 } else if (p->lettre > mot[i]) {
70 NOEUD *p1 = insere_fin(mot, i);
71 p1->frere = p;
72 p = p1;
73 } else {
74 p->frere = insere(p->frere, mot, i);
75 }
76 return p;
77}
78
79/*****************************************************************************/
80/* Affichage par ordre alphabetique de tous les mots stockes dans l'arbre */
81void affiche(NOEUD * p, char *mot, int i)
82{
83 /* i est l'indice de la lettre courante dans le mot */
84 if (p != NULL) {
85 mot[i] = p->lettre;
86 affiche(p->fils, mot, i + 1);
87 if (mot[i] == '\0') {
88 printf("%s\n", mot);
89 }
90 affiche(p->frere, mot, i);
91 }
92}
93
94/* Visualisation de l'arbre n-aire *******************************************/
95void affiche_arbre(NOEUD * p, int prof)
96/* prof est utilise pour decaller l'affichage avec des espaces (selon le niveau dans l'arbre) */
97{
98 int i;
99
100 if (p) {
101 affiche_arbre(p->frere, prof);
102 for (i = 0; i < prof; i++)
103 printf(" ");
104 printf("%c\n", p->lettre);
105 affiche_arbre(p->fils, prof + 1);
106 }
107}
108
109/* Suppression d'un mot de l'arbre ********************************************/
110/* Attention a ne supprimer que la fin du mot qui n'est partagee par aucun autre mot de l'arbre */
111NOEUD *supprime(NOEUD * p, char *mot, int i)
112/* i est l'indice de la lettre courante dans le mot */
113{
114 if (p) {
115 if (p->lettre < mot[i]) {
116 p->frere = supprime(p->frere, mot, i);
117 } else if (p->lettre == mot[i]) {
118 p->fils = supprime(p->fils, mot, i + 1);
119 if (!p->fils) {
120 NOEUD *p1 = p;
121 p = p->frere;
122 free(p1);
123 }
124 return p;
125 }
126 }
127}
128
129/* Destruction des arbres de racine p en recuperant la place occupee (free) par chacun des noeuds */
130NOEUD *detruis_arbre(NOEUD * p)
131{
132 if (p == NULL)
133 return p;
134 else {
135 p->fils = detruis_arbre(p->fils);
136 p->frere = detruis_arbre(p->frere);
137 free(p);
138 p = NULL;
139 return p;
140 }
141}
142
143/* Chargement des mots d'un fichier (vu comme un dictionnaire) dans l'arbre **/
144NOEUD *charge_dico(char *nom_fichier, int *nb_mots)
145{
146 NOEUD *p;
147 FILE *fp;
148 char mot[N];
149 int i;
150 p = NULL;
151
152 fp = fopen(nom_fichier, "rt");
153 if (fp == NULL)
154 exit(-1);
155 fscanf(fp, "%d", nb_mots); /* sur la 1ere ligne du fichier, le nombre de mots */
156 for (i = 0; i < *nb_mots; i++) {
157 fscanf(fp, "%s", mot);
158 p = insere(p, mot, 0);
159 }
160 fclose(fp);
161 return p;
162}
163
164/* Ecriture dans fp de tous les mots stockes dans l'arbre ********************/
165void affiche_fich(FILE * fp, NOEUD * p, char *mot, int i)
166{
167 /* i est l'indice de la lettre courante dans le mot */
168 if (p != NULL) {
169 mot[i] = p->lettre;
170 affiche_fich(fp, p->fils, mot, i + 1);
171 if (mot[i] == '\0') {
172 fprintf(fp, "%s\n", mot);
173 }
174 affiche_fich(fp, p->frere, mot, i);
175 }
176}
177
178/* Sauvegarde des mots de l'arbre dans un fichier ****************************/
179void sauve_dico(NOEUD * p, char *nom_fichier, int nb_mots)
180{
181 FILE *fp;
182 char mot[N];
183
184 fp = fopen(nom_fichier, "wt");
185 if (fp == NULL)
186 exit(-1);
187 fprintf(fp, "%d\n", nb_mots);
188 affiche_fich(fp, p, mot, 0);
189 fclose(fp);
190}
191
192/*****************************************************************************/
193int main(int argc, char *argv[])
194{
195 char mot[N];
196 int nb_mots = 0;
197 NOEUD *arbre = NULL;
198
199 //printf ("saisir un mot : ");
200 //gets (mot);
201 //printf ("\ninsertion de %s\n", mot);
202 //arbre = insere (arbre, mot, 0);
203 arbre = charge_dico("dictionnaire", &nb_mots);
204 printf("\naffichage mots :\n");
205 affiche(arbre, mot, 0);
206 printf("\naffichage arbre :\n");
207 affiche_arbre(arbre, 0);
208 if (recherche(arbre, "salut", 0))
209 printf("mot \"salut\" present\n");
210 sauve_dico(arbre, "dictionnaire_debug", nb_mots);
211 supprime(arbre, "zazou", 0);
212 affiche_arbre(arbre, 0);
213 detruis_arbre(arbre);
214 if (!arbre)
215 affiche_arbre(arbre, 0);
216 /* TODO */
217}
218
219/* Exemple de trace d'execution *************************
220
221saisir un mot : salut
222
223insertion de salut
224insere_fin s, 0
225insere_fin a, 1
226insere_fin l, 2
227insere_fin u, 3
228insere_fin t, 4
229insere_fin , 5
230
231affichage arbre :
232s
233 a
234 l
235 u
236 t
237
238... TODO ...
239
240**********************************************************/