Binar copac de căutare binară în interiorul arborelui de căutare

voturi
0

Am o temă care cere de la mine pentru a crea un struct de arbore binar de căutare în cazul în care nodul de arbore binar de căutare este un alt arbore binar de căutare. Primul BST are numele de familie al Studenților, iar cealaltă are primele nume și ID-ul. De asemenea, dacă cineva are același nume de familie cu un alt student nu trebuie să creeze un alt „nume“ nod, dar trebuie să creeze în interiorul nodului „numele“ existent alt „nume și ID-ul de“ nod. Pentru a fi mai specific:

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;

Principala mea problema este modul de a crea un nod nameANDid diferit pentru fiecare firstname am găsit că, cu următorul cod am crea 2 unul BST pentru numele de familie și un altul pentru nume, dar aș dori să fiu ca de exemplu: Dacă am acești studenți

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

Vreau să le stocați așa: .........

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

În loc de acest lucru eu iau ceva de genul: ...........

 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

Voi pune aici unele funcții pentru a fi mai specific

Funcția de încărcare încarcă numele dintr-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);  
}

Unde

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

Funcția addNode este: ...

      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;
         }

Și add_node_nameANDid () funcția este ca funcția anterioară, dar are unele variabile schimbat:

      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;
    }

Ne pare rău pentru codul sursă imens pe care tocmai l-am încărcat, dar ar fi foarte dificil de explicat fără ca acest lucru.

Cred că am două probleme, dar nu am cunoștințele necesare pentru a le rezolva.

PRIMUL: Trebuie să creeze diferite BST firstname pentru fiecare nod nume de familie și cred că eu nu fac asta, dar eu nu știu cum să fac asta ...

Orice sugestii?

Întrebat 29/05/2011 la 12:22
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
2

Am dat un exemplu de implementare a acestui mai jos, a comentat pentru a explica modul în care am abordat acest lucru. Tu ar trebui să poată folosi ideile mele pentru a modifica modul în care funcționează codul. Rețineți că sa nu o implementare perfectă, pe partea de sus a capului meu, pot vedea următoarele probleme.

  1. Sa recursiv , ceea ce înseamnă că adâncimea arborelui se poate ocupa este limitată de dimensiunea stivei de pe mașina țintă. Există două modalități prin care pot ataca acest lucru, fie:
    1. Fă - l iterativ . Aceasta este, utilizarea for/ whilebucle în loc de funcții care se numesc - acest lucru ar permite ca mai multe noduri ca memorie mașini pot ocupa (rezolvă problema).
    2. Actualizare add_name_to_treesă se ocupe de inserții pentru un arbore binar echilibrat (dar acest lucru ajută doar problema, limita stiva este încă acolo).
  2. Ea nu se poate ocupa două persoane cu exact același nume, dar diferite de identitate - după prima persoană care se adaugă la copac, toți oamenii ulterioare de același nume sunt ignorate.

Am va lăsa ca un exercițiu pentru tine să se ocupe de aceste situații.


#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;
}
Publicat 29/05/2011 la 23:46
sursa de către utilizator

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