TP6: n-ary tree: add insert and destroy functions
[Algorithmic_C.git] / TP6 / arbres / arbre_n_aire / arbre_n_aire.c
CommitLineData
89bde9ea 1/*****************************************************************************/
89bde9ea
JB
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
e06ddf2d
JB
14typedef struct noeud {
15 char lettre;
16 struct noeud *fils;
17 struct noeud *frere;
89bde9ea
JB
18} NOEUD;
19
20/* Recherche d'un mot dans l'arbre *****************************************/
e06ddf2d 21bool recherche(NOEUD * p, char *mot, int i)
89bde9ea 22{
e06ddf2d
JB
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);
89bde9ea 30 }
e06ddf2d
JB
31 } else {
32 if (p->lettre > mot[i]) {
33 return false;
34 } else {
35 return recherche(p->frere, mot, i);
89bde9ea
JB
36 }
37 }
38}
39
40/* Creation d'une fin de mot (liste chainee suivant le lien fils) **********/
e06ddf2d 41NOEUD *insere_fin(char *mot, int i)
89bde9ea 42{
e06ddf2d
JB
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;
89bde9ea
JB
54}
55
56/* Insertion d'un mot dans l'arbre ******************************************/
57/* (on respecte l'ordre lexicographique des freres)**************************/
91549585 58NOEUD *_insere(NOEUD * p, char *mot, int i)
dfa8da5e 59{
e06ddf2d 60 /* i est l'indice de la lettre courante dans le mot */
760a8310
JB
61 if (p == NULL) {
62 return insere_fin(mot, i);
e06ddf2d 63 }
e06ddf2d 64 if (mot[i] > p->lettre) {
91549585 65 return _insere(p->frere, mot, i);
760a8310 66 } else if (mot[i] == p->lettre) {
91549585
JB
67 return _insere(p->fils, mot, i + 1);
68 } else if (mot[i] < p->lettre) {
69 return _insere(p->fils, mot, i);
e06ddf2d 70 }
89bde9ea
JB
71}
72
91549585
JB
73NOEUD *insere(NOEUD * p, char *mot, int i)
74{
75 p = _insere(p, mot, i);
76 return p;
77}
78
89bde9ea
JB
79/*****************************************************************************/
80/* Affichage par ordre alphabetique de tous les mots stockes dans l'arbre */
e06ddf2d 81void affiche(NOEUD * p, char *mot, int i)
dfa8da5e 82{
e06ddf2d
JB
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);
7a4d5d57 89 }
e06ddf2d 90 affiche(p->frere, mot, i);
7a4d5d57 91 }
89bde9ea
JB
92}
93
94/* Visualisation de l'arbre n-aire *******************************************/
e06ddf2d 95void affiche_arbre(NOEUD * p, int prof)
dfa8da5e 96/* prof est utilise pour decaller l'affichage avec des espaces (selon le niveau dans l'arbre) */
89bde9ea 97{
e06ddf2d 98 int i;
760a8310 99
e06ddf2d
JB
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);
89bde9ea
JB
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 */
e06ddf2d 111NOEUD *supprime(NOEUD * p, char *mot, int i)
dfa8da5e 112/* i est l'indice de la lettre courante dans le mot */
89bde9ea 113{
e06ddf2d
JB
114 /* TODO */
115 return p;
89bde9ea
JB
116}
117
e945a5c8
JB
118/* Destruction des arbres de racine p en recuperant la place occupee (free) par chacun des noeuds */
119NOEUD *detruis_arbre(NOEUD * p)
120{
121 if (p == NULL)
122 return p;
123 else {
124 p->fils = detruis_arbre(p->fils);
125 p->frere = detruis_arbre(p->frere);
126 free(p);
127 p = NULL;
128 return p;
129 }
130}
131
89bde9ea 132/* Chargement des mots d'un fichier (vu comme un dictionnaire) dans l'arbre **/
e06ddf2d 133NOEUD *charge_dico(char *nom_fichier, int *nb_mots)
89bde9ea 134{
e06ddf2d
JB
135 NOEUD *p;
136 FILE *fp;
137 char mot[N];
138 int i;
139 p = NULL;
760a8310 140
e06ddf2d
JB
141 fp = fopen(nom_fichier, "rt");
142 if (fp == NULL)
143 exit(-1);
144 fscanf(fp, "%d", nb_mots); /* sur la 1ere ligne du fichier, le nombre de mots */
145 for (i = 0; i < *nb_mots; i++) {
146 fscanf(fp, "%s", mot);
147 p = insere(p, mot, 0);
89bde9ea 148 }
e06ddf2d
JB
149 fclose(fp);
150 return p;
89bde9ea
JB
151}
152
153/* Ecriture dans fp de tous les mots stockes dans l'arbre ********************/
e06ddf2d 154void affiche_fich(FILE * fp, NOEUD * p, char *mot, int i)
89bde9ea 155{
91549585
JB
156 /* i est l'indice de la lettre courante dans le mot */
157 if (p != NULL) {
158 mot[i] = p->lettre;
159 affiche_fich(fp, p->fils, mot, i + 1);
160 if (mot[i] == '\0') {
161 fprintf(fp, "%s\n", mot);
162 }
163 affiche_fich(fp, p->frere, mot, i);
164 }
89bde9ea
JB
165}
166
167/* Sauvegarde des mots de l'arbre dans un fichier ****************************/
e06ddf2d 168void sauve_dico(NOEUD * p, char *nom_fichier, int nb_mots)
89bde9ea 169{
e06ddf2d
JB
170 FILE *fp;
171 char mot[N];
760a8310 172
e06ddf2d
JB
173 fp = fopen(nom_fichier, "wt");
174 if (fp == NULL)
175 exit(-1);
176 fprintf(fp, "%d\n", nb_mots);
91549585 177 affiche_fich(fp, p, mot, 0);
e06ddf2d 178 fclose(fp);
89bde9ea
JB
179}
180
181/*****************************************************************************/
e06ddf2d 182int main(int argc, char *argv[])
89bde9ea 183{
e06ddf2d
JB
184 char mot[N];
185 int nb_mots = 0;
186 NOEUD *arbre = NULL;
760a8310 187
e06ddf2d
JB
188 //printf ("saisir un mot : ");
189 //gets (mot);
190 //printf ("\ninsertion de %s\n", mot);
191 //arbre = insere (arbre, mot, 0);
192 arbre = charge_dico("dictionnaire", &nb_mots);
193 printf("\naffichage mots :\n");
194 affiche(arbre, mot, 0);
195 printf("\naffichage arbre :\n");
196 affiche_arbre(arbre, 0);
197 if (recherche(arbre, "salut", 0))
198 printf("mot \"salut\" present\n");
91549585 199 sauve_dico(arbre, "dictionnaire_debug", nb_mots);
e945a5c8 200 detruis_arbre(arbre);
91549585
JB
201 if (!arbre)
202 affiche_arbre(arbre, 0);
e06ddf2d 203 /* TODO */
89bde9ea
JB
204}
205
206/* Exemple de trace d'execution *************************
207
208saisir un mot : salut
209
210insertion de salut
211insere_fin s, 0
212insere_fin a, 1
213insere_fin l, 2
214insere_fin u, 3
215insere_fin t, 4
216insere_fin , 5
217
218affichage arbre :
219s
220 a
221 l
222 u
223 t
224
225... TODO ...
226
227**********************************************************/