Arbre binaire de recherche dans l'arbre de recherche binaire

voix
0

J'ai un devoir qui demande de moi de créer un struct d'arbre de recherche binaire où le nœud de l'arbre de recherche binaire est un autre arbre de recherche binaire. Le premier BST a les noms des étudiants et l'autre a les prénoms et id. Aussi, si quelqu'un a le même nom avec un autre étudiant, je ne dois pas créer un autre noeud « nom de famille » mais je dois créer à l'intérieur du noeud « nom de famille » existant un autre noeud « prénom et Id ». Pour être plus précis:

typedef struct nameANDid{ //name and id nodes
    char first[20];
    int ID;
    struct nameANDid *nleft;
    struct nameANDid *nright;
}yohoho;
typedef struct node{  //surname nodes
   char last[20];  
   struct nameANDid yohoho;  
   struct node *left;
   struct node *right;
}node;

Mon principal problème est de savoir comment créer un noeud nameANDid différent pour chaque prenom j'ai trouvé car avec le code suivant je crée 2 BST un pour les noms de famille et un autre pour les noms mais je voudrais être comme par exemple: Si j'ai ces étudiants

 Stallone Sylvester 11111111
 Stallone Noah      22222222
 Norris   Chuck     33333333
 Hogan    Hulk      44444444
 Hogan    Daniel    55555555

Je veux les stocker comme ceci: .........

 Stallone Sylvester 11111111
          Noah      22222222
 Norris   Chuck     33333333
 Hogan    Hulk      44444444
          Daniel    55555555

Au lieu de cela, je prends quelque chose comme: ...........

 Stallone  Sylvester 11111111.
           Noah      22222222 
           Chuck     33333333
           Hulk      44444444 
           Daniel    55555555

 Norris  Sylvester 11111111.
           Noah      22222222 
           Chuck     33333333
           Hulk      44444444 
           Daniel    55555555
 Hogan    Sylvester 11111111.
           Noah      22222222 
           Chuck     33333333
           Hulk      44444444 
           Daniel    55555555

Je mettrai ici quelques fonctions afin d'être plus précis

La fonction de charge charge les noms d'un document txt.

void loadData(struct node *temp){      
int i;
FILE *fp;
fp=fopen(FILENAME,r);
if (fp == NULL) printf(File does not exist\n);
for (i=0; i<5; i++){                
    fscanf(fp,%s,&temp->last);
    fscanf(fp,%s,&temp->yohoho.first);
    fscanf(fp,%d,&temp->yohoho.ID);                 
    top=add_node(top,temp);  //this function create a surname node        
    }        
fclose(fp);     
    printf(\n\nFile loaded\n);  
}

        struct node temp;//just  a node pointer
        struct node *top=NULL; //shows the top of the tree

La fonction est addnode: ...

      struct node * add_node (struct node *top, struct node *temp){  
           struct node *newNode;  
           if (top == NULL){    
           newNode=(struct node *)malloc(sizeof(struct node));
           temp->left=NULL;
           temp->right=NULL;     
           if (memcpy(newNode,temp,sizeof(struct node)) == NULL){
               printf(Node addition failed\n);
               return NULL;}
           else {             
               topname=add_node_nameANDid(topname,&temp->yohoho); //Call the add_node_nameANDid to create a new name node in the other tree                           
               return newNode;}
            }
           else {   
               if (stricmp(temp->last,top->last) < 0){ //Insert node surname left
                     top->left=add_node(top->left,temp);}
               else if (stricmp(temp->last,top->last) == 0){         
                     topname=add_node_nameANDid(topname,&temp->yohoho);  //Call the add_node_nameANDid to create a new name node in the other tree   if i have the same surname        
               }
               else {
                     top->right=add_node(top->right,temp);           
               }
               return top;
             } 
             return NULL;
         }

Et la fonction add_node_nameANDid () est comme la fonction précédente, mais il a changé certaines variables:

      struct nameANDid * add_node_nameANDid (struct nameANDid *topname, struct nameANDid *temp2){
        struct nameANDid *newNode_nameANDid;     
        if (topname == NULL){ 
            newNode_nameANDid=(struct nameANDid *)malloc(sizeof(struct nameANDid));
            temp2->nleft=NULL;
            temp2->nright=NULL;
            if (memcpy(newNode_nameANDid,temp2,sizeof(struct nameANDid)) == NULL){
                   printf(Node addition failed\n);
                   return NULL;}
            else {                 
                   return newNode_nameANDid;}
            }
        else {   
             if (stricmp(temp2->first,topname->first) <= 0){       
                  topname->nleft=add_node_nameANDid(topname->nleft,temp2);}
        else {         
                  topname->nright=add_node_nameANDid(topname->nright,temp2);}  
        return topname;
        } 
     return NULL;
    }

Désolé pour le grand code source que je vous suffit de télécharger, mais il serait très difficile d'expliquer sans cela.

Je pense que j'ai deux problèmes, mais je n'ai pas les connaissances nécessaires pour les résoudre.

PREMIER: Je dois créer différents prenom BST pour chaque nœud de nom et je pense que je ne fais pas ça, mais je ne sais pas comment faire ...

Aucune suggestion?

Créé 29/05/2011 à 12:22
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
2

J'ai donné un exemple d'implémentation de ce ci-dessous, a commenté pour expliquer comment je me suis approché ce sujet. Vous devriez être en mesure d'utiliser mes idées pour modifier la façon dont votre code. Notez que ce ne est pas une mise en œuvre parfaite, du haut de ma tête, je peux voir les problèmes suivants.

  1. Son récursif , ce qui signifie que la profondeur de l' arbre , il peut prendre en charge est limitée par la taille de la pile sur la machine cible. Il y a deux façons dont vous pouvez attaquer ce, que ce soit:
    1. Faites - itérative . C'est, l' utilisation for/ whileboucles au lieu des fonctions se faisant appeler - cela permettrait autant de nœuds que vos machines mémoire peut gérer (résout le problème).
    2. Mise à jour add_name_to_treepour gérer les insertions pour un arbre binaire équilibré (mais cela permet simplement à la question, la limite de la pile est toujours là).
  2. Il ne peut pas gérer deux personnes avec exactement le même nom, mais différents - après son ID la première personne est ajoutée à l'arbre, toutes les personnes suivantes du même nom sont ignorés.

Je laisse comme un exercice pour vous de gérer ces situations.


#include <stdio.h>
#include <string.h>

/* a single struct type for storing all tree elements */
typedef struct _node
{
    char name[50];
    int id;
    struct _node *subname;
    struct _node *left;
    struct _node *right;
} node;

/* creates a new node structure for the specified name and id */
node *create_node(const char *name, int id)
{
    node *newNode = (node*)malloc(sizeof(node));
    memset(newNode, 0, sizeof(*newNode));

    newNode->id = id;
    strncpy(newNode->name, name, sizeof(newNode->name));

    return newNode;
}

/* inserts the name/id pair into the tree specified by root.
   note that root is passed as a pointer to a pointer, so that
   it can accept NULL if no tree exists yet, and return to the 
   caller the node the node that contains the name.  Note that
   id is ignored if "name" already exists, i'll leave it as an
   excersice for you to handle situations with the same name
   with multiple id's */
node *add_name_to_tree(node **root, const char *name, int id)
{
    if (*root == NULL)
    {
        *root = create_node(name, id);
        return *root;
    }

    const int cmp = strcmp(name, (*root)->name);

    if (cmp < 0)
    {
        return add_name_to_tree(&(*root)->left, name, id);
    }
    else if (cmp > 0)
    {
        return add_name_to_tree(&(*root)->right, name, id);
    }
    else
    {
        return *root;
    }
}

/* adds the specified first/last name and id combo to the tree
   specified by root */
node *add_name(node *root, const char *first, const char *last, int id)
{
    /* this call will return the node that holds the last name,
       we can then use its "subname" tree root to insert the first name */
    node *last_node = add_name_to_tree(&root, last, 0);

    /* use the "subname" of the node that stores the last name as the 
       root of the tree that stores first names */
    add_name_to_tree(&last_node->subname, first, id);
    return root;
}

/* just to demonstrate why I use the same node type for first/last names,
   its because it allows you to support any number of names, see
   below - an add function that adds people with a middle name to the tree
   */
node *add_with_middle_name(node *root, const char *first, 
                           const char *middle, const char *last, int id)
{
    node *last_node = add_name_to_tree(&root, last, 0);
    node *mid_node = add_name_to_tree(&last_node->subname, middle, 0);
    add_name_to_tree(&mid_node->subname, first, id);
    return root;
}

/* recursively traverse the name tree, printing out the names */
void print_names(node *names, int level)
{
    const int indent = 10;

    if (names == NULL)
    {
        printf("\n");
    }

    if (names->left)
    {
        print_names(names->left, level);
    }

    if (names->subname)
    {
        printf("%*c %s \n", (indent * level), ' ', names->name);
        print_names(names->subname, level + 1);
        printf("\n");
    }
    else
    {
        printf("%*c %-*s %d\n", 
               (indent * level), ' ', 
               indent, names->name, names->id);
    }

    if (names->right)
    {
        print_names(names->right, level);
    }
}

int main()
{
    node *names = NULL;

    names = add_name(names, "Sylvester", "Stallone", 11111111);
    names = add_name(names, "Noah", "Stallone", 22222222);
    names = add_name(names, "Chuck", "Norris", 33333333);
    names = add_name(names, "Hulk", "Hogan", 44444444);
    names = add_name(names, "Daniel", "Hogan", 55555555);

    names = add_with_middle_name(names, "Peter", "Michael", 
                                 "Zachson", 66666666);

    print_names(names, 0);

    return 0;
}
Créé 29/05/2011 à 23:46
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more