Partage
  • Partager sur Facebook
  • Partager sur Twitter

construire un arbre lexicographique et l'afficher

    5 mars 2023 à 11:30:08

    Bonjour,

    j'essaie de construire un arbre lexicographique à l'aide d'un fichier pris en argument dans le main, mais il m'affiche un arbre rempli de (null) avec si j'ai de la chance le premier mot de la dernière phrase comme racine.

    Le fichier contient le texte suivant   :

    Un arbre binaire est une structure de données
    qui peut se représenter sous la forme d’une hiérarchie
    dont chaque élément est appelé noeud.

    #include <stdio.h>
    #include <string.h>
     
    #define TAILLE 512
    
    
    typedef struct noeud {
        char * mot;
        struct noeud *fg, *fd;
    } Noeud, *Arbre;
    
    
    Noeud * alloue_noeud(char * mot){
        /*
        allocation d’un nœud en recopiant strictement 
        la chaîne de caractères passée en argument
        */
        Noeud * n = (Noeud*) malloc(sizeof(Noeud));
        if (n){
            if ('A' <= *mot && *mot <= 'Z'){
                n->mot = mot ; // Transformation maj -> min    
                n->fg = n->fd = NULL;
            }
        }
        return n;
    
    }
    
    Noeud * ajout(Arbre *A, char * mot){
    /* Renvoie l'adresse du noeud contenant x */
        
       
        if (*A == NULL) {
            //printf(" hi ");
            *A = alloue_noeud(mot);
            return *A;
        }
        
        if (mot == (*A)-> mot)
            //printf("%s\n" ,(*A)->mot);
    
            return *A; /* x est a la racine */
        if (mot < (*A)->mot){
            return ajout(&((*A)->fg), mot);
        }
        else{ /* x > (*A)->mot */
            return ajout(&((*A)->fd), mot);
        }
    }
    
    
    int cree_arbre(FILE* fichier, Arbre * A){
    
        char chaine[TAILLE];
        const char * separators = " \n,;:.?!\"()-’";
        char * tokens ;
        while(fgets( chaine, TAILLE ,fichier) != NULL){
            
            tokens = strtok ( chaine, separators );
                    //A = alloue_noeud(tokens);
            while (tokens != 0){
                printf("%s\n" , tokens);
               
                ajout(A , tokens );
                
                tokens = strtok ( NULL, separators );  // on demande le block suivant
    
            }
        }
        return 1 ;
    }
    
    
    void parcours_infixe(Arbre A){
        /*
        affichage des mots contenus dans l’arbre A, 
        un par ligne, sur la sortie standard dans l’ordre d’un parcours
        en profondeur infixe de A
        */
       if (A != NULL){
            parcours_infixe(A->fg);
            printf("%s\n" ,A->mot);
            parcours_infixe(A->fd);
       }
    
    }
    
    
    int main(int argc , char *argv[]){
        Arbre A = NULL;
       
        FILE* texte = fopen(argv[1],"r");
        cree_arbre(texte,&A);
        parcours_infixe(A);
        
        return 0;
    }
    



    Comment pourrais-je corriger cette erreur .

    Je vous remercie d'avance

    -
    Edité par LaureDeze 5 mars 2023 à 11:33:05

    • Partager sur Facebook
    • Partager sur Twitter
      5 mars 2023 à 12:04:32

      Bonjour,

      ton code souffre de pas mal d'erreurs qui sont soit des erreurs typiques en C (cast sur le malloc, cacher un pointeur dans un typedef, patage hasardeux de portions de mémoire dû à l'incompréhension de l'utilisation de strtok, mécompréhension d'utilisation de char vs char*…) soit des erreurs d'algo. Avant de vouloir coder quoi que soit il faut que tu aies écrit les algos. Ici par exemple tu utilises une représentation fils gauche/frère droit pour l'implémentation d'un arbre préfixe.

      Pourrais-tu me donner l'algo (et pas le code) d'une insertion ?

      • Partager sur Facebook
      • Partager sur Twitter
        5 mars 2023 à 12:48:21

        insertion(Arbre *A, char mot)
        Si A est nulle
        Insérer le mot
        
        Sinon
        Si filsgauche n'est pas vide
        Appel récursif sur filsgauche
        
        Si filsdroit n'est pas vide
        Appel récursif sur filsdroit

         Ah oui je suis obligée d'utiliser strtok dans la fonction creer_arbre

        -
        Edité par LaureDeze 5 mars 2023 à 12:59:19

        • Partager sur Facebook
        • Partager sur Twitter
          5 mars 2023 à 16:59:15

          Juste pour clarifier les choses et éviter un problème XY, veux-tu :

          • un arbre préfixe contenant des mots ;
          • un arbre binaire de recherche contenant des mots.
          • Partager sur Facebook
          • Partager sur Twitter
            5 mars 2023 à 18:55:48

            Vu que je fais un parcours  infixe pour afficher mon arbre du coup , je veux un arbre binaire de recherche contenant des mots . donc je me suis trompée

            Du coup, je dois faire ça ???? :

            insertion(Arbre *A, char mot)
            Si A est nulle
            Insérer le mot
             
            Sinon
            Si filsgauche n'est pas vide et racine est supérieure ou égale au mot
            Appel récursif sur filsgauche
             
            Si filsdroit n'est pas vide et racine est inférieure au mot 
            Appel récursif sur filsdroit



            -
            Edité par LaureDeze 5 mars 2023 à 19:00:23

            • Partager sur Facebook
            • Partager sur Twitter
              5 mars 2023 à 19:19:26

              Je crois qu'il y a le même problème que dans ce programme

              #include <stdio.h>
              
              int main()
              {
              	char mot[100];
              	char *premier, *second;
              
              	printf("Premier mot ? ");
              	scanf("%s", mot);
              	premier = mot;
              
              	printf("Second mot ? ");
              	scanf("%s", mot);
              	second = mot;
              
              	printf("les mots sont '%s' et '%s'\n", premier, second);
              	
              	return 0;
              
              }
              

              dont l'exécution peut paraître étrange

              $ make a
              cc     a.c   -o a
              
              $ ./a
              Premier mot ? truc
              Second mot ? machin
              les mots sont 'machin' et 'machin'
              
              


              Cause: les chaînes de caractères ne sont pas vraiment des objets du langage C. Il y a des tableaux de caractères, et des pointeurs de caractères....  Copier un pointeur, ce n'est pas copier la chaîne qu'il désigne.

              -
              Edité par michelbillaud 5 mars 2023 à 19:22:46

              • Partager sur Facebook
              • Partager sur Twitter
                6 mars 2023 à 2:44:46

                Ce n'est pas tout à fait la bonne façon de comparer des chaînes de caractères:
                    if (mot < (*A)->mot){
                        return ajout(&((*A)->fg), mot);
                Voir strcmp()
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  6 mars 2023 à 22:12:39

                  j'ai trouvé , c'était un problème avec ma fonction alloue_noeud et oui il y avait bien un problème de pointeur  merci mais  du coup pour comparer c'est préférable d'utiliser strcmp ????
                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 mars 2023 à 1:11:46

                    strcmp est la fonction à utiliser pour comparer des chaînes de caractères.
                    Toi, tu compares encore des adresses (ou pointeurs) qui seront n'importe quoi.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Le Tout est souvent plus grand que la somme de ses parties.

                    construire un arbre lexicographique et l'afficher

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown