TP6 n ary tree: fix the insert function
[Algorithmic_C.git] / TP6 / arbres / arbre_n_aire / arbre_n_aire.c
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
14 typedef struct noeud {
15 char lettre;
16 struct noeud *fils;
17 struct noeud *frere;
18 } NOEUD;
19
20 /* Recherche d'un mot dans l'arbre *****************************************/
21 bool 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) **********/
41 NOEUD *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)**************************/
58 NOEUD *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]) {
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 /*****************************************************************************/
81 /* Affichage par ordre alphabetique de tous les mots stockes dans l'arbre */
82 void affiche(NOEUD * p, char *mot, int i)
83 {
84 /* i est l'indice de la lettre courante dans le mot */
85 if (p != NULL) {
86 mot[i] = p->lettre;
87 affiche(p->fils, mot, i + 1);
88 if (mot[i] == '\0') {
89 printf("%s\n", mot);
90 }
91 affiche(p->frere, mot, i);
92 }
93 }
94
95 /* Visualisation de l'arbre n-aire *******************************************/
96 void affiche_arbre(NOEUD * p, int prof)
97 /* prof est utilise pour decaller l'affichage avec des espaces (selon le niveau dans l'arbre) */
98 {
99 int i;
100
101 if (p) {
102 affiche_arbre(p->frere, prof);
103 for (i = 0; i < prof; i++)
104 printf(" ");
105 printf("%c\n", p->lettre);
106 affiche_arbre(p->fils, prof + 1);
107 }
108 }
109
110 /* Suppression d'un mot de l'arbre ********************************************/
111 /* Attention a ne supprimer que la fin du mot qui n'est partagee par aucun autre mot de l'arbre */
112 NOEUD *supprime(NOEUD * p, char *mot, int i)
113 /* i est l'indice de la lettre courante dans le mot */
114 {
115 /* TODO */
116 return p;
117 }
118
119 /* Destruction des arbres de racine p en recuperant la place occupee (free) par chacun des noeuds */
120 NOEUD *detruis_arbre(NOEUD * p)
121 {
122 if (p == NULL)
123 return p;
124 else {
125 p->fils = detruis_arbre(p->fils);
126 p->frere = detruis_arbre(p->frere);
127 free(p);
128 p = NULL;
129 return p;
130 }
131 }
132
133 /* Chargement des mots d'un fichier (vu comme un dictionnaire) dans l'arbre **/
134 NOEUD *charge_dico(char *nom_fichier, int *nb_mots)
135 {
136 NOEUD *p;
137 FILE *fp;
138 char mot[N];
139 int i;
140 p = NULL;
141
142 fp = fopen(nom_fichier, "rt");
143 if (fp == NULL)
144 exit(-1);
145 fscanf(fp, "%d", nb_mots); /* sur la 1ere ligne du fichier, le nombre de mots */
146 for (i = 0; i < *nb_mots; i++) {
147 fscanf(fp, "%s", mot);
148 p = insere(p, mot, 0);
149 }
150 fclose(fp);
151 return p;
152 }
153
154 /* Ecriture dans fp de tous les mots stockes dans l'arbre ********************/
155 void affiche_fich(FILE * fp, NOEUD * p, char *mot, int i)
156 {
157 /* i est l'indice de la lettre courante dans le mot */
158 if (p != NULL) {
159 mot[i] = p->lettre;
160 affiche_fich(fp, p->fils, mot, i + 1);
161 if (mot[i] == '\0') {
162 fprintf(fp, "%s\n", mot);
163 }
164 affiche_fich(fp, p->frere, mot, i);
165 }
166 }
167
168 /* Sauvegarde des mots de l'arbre dans un fichier ****************************/
169 void sauve_dico(NOEUD * p, char *nom_fichier, int nb_mots)
170 {
171 FILE *fp;
172 char mot[N];
173
174 fp = fopen(nom_fichier, "wt");
175 if (fp == NULL)
176 exit(-1);
177 fprintf(fp, "%d\n", nb_mots);
178 affiche_fich(fp, p, mot, 0);
179 fclose(fp);
180 }
181
182 /*****************************************************************************/
183 int main(int argc, char *argv[])
184 {
185 char mot[N];
186 int nb_mots = 0;
187 NOEUD *arbre = NULL;
188
189 //printf ("saisir un mot : ");
190 //gets (mot);
191 //printf ("\ninsertion de %s\n", mot);
192 //arbre = insere (arbre, mot, 0);
193 arbre = charge_dico("dictionnaire", &nb_mots);
194 printf("\naffichage mots :\n");
195 affiche(arbre, mot, 0);
196 printf("\naffichage arbre :\n");
197 affiche_arbre(arbre, 0);
198 if (recherche(arbre, "salut", 0))
199 printf("mot \"salut\" present\n");
200 sauve_dico(arbre, "dictionnaire_debug", nb_mots);
201 detruis_arbre(arbre);
202 if (!arbre)
203 affiche_arbre(arbre, 0);
204 /* TODO */
205 }
206
207 /* Exemple de trace d'execution *************************
208
209 saisir un mot : salut
210
211 insertion de salut
212 insere_fin s, 0
213 insere_fin a, 1
214 insere_fin l, 2
215 insere_fin u, 3
216 insere_fin t, 4
217 insere_fin , 5
218
219 affichage arbre :
220 s
221 a
222 l
223 u
224 t
225
226 ... TODO ...
227
228 **********************************************************/