Binary Search boom binnen Binary Zoekboom

stemmen
0

Ik heb een huiswerk, die vragen van mij voor een structuur van binaire zoekboom te creëren waar het knooppunt van de binaire zoekboom is een andere binaire zoekboom. De eerste BST heeft de achternamen van studenten en de andere heeft de eerste namen en id. Ook als iemand heeft dezelfde achternaam met een andere student moet ik een andere achternaam knooppunt niet maken, maar ik moet maken binnen de bestaande achternaam knooppunt een ander voornaam en Id node. Om meer specifiek te zijn:

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;

Mijn grootste probleem is hoe u een andere nameANDid knooppunt voor elke voornaam vond ik, want met de volgende code te maken maak ik 2 BST een voor de achternamen en een andere voor de namen, maar ik zou willen zijn zoals bijvoorbeeld: Als ik deze studenten

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

Ik wil ze op te slaan als volgt: .........

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

In plaats daarvan neem ik iets als: ...........

 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

Ik zal hier enkele functies om meer specifiek te zijn gezet

De belasting functie laadt de namen uit een txt document.

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

waar

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

De AddNode functie is: ...

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

En de add_node_nameANDid () functie is net als de vorige functie, maar het heeft een aantal variabelen veranderd:

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

Sorry voor de enorme bron code die ik alleen het uploaden, maar het zou heel moeilijk uit te leggen, zonder dat dit zijn.

Ik denk dat ik twee problemen, maar ik heb niet de kennis om ze op te lossen hebben.

EERSTE: Ik heb om verschillende voornaam BST te creëren voor elke achternaam knooppunt en ik denk dat ik dat niet doe, maar ik weet niet hoe dat te doen ...

Eventuele suggesties?

De vraag is gesteld op 29/05/2011 om 12:22
bron van user
In andere talen...                            


1 antwoorden

stemmen
2

Ik heb een voorbeeld uitvoering van deze hieronder, commentaar uit te leggen hoe ik dit benaderde gegeven. Je moet in staat zijn om mijn ideeën te gebruiken om de manier waarop uw code werkt aan te passen. Merk op dat het niet een perfecte uitvoering van de bovenkant van mijn hoofd, kan ik de volgende problemen zich voordoen.

  1. De recursieve , waarbij de diepte van de boom kan handgreeporgaan wordt beperkt door de grootte van de stapel op de doelcomputer. Er zijn twee manieren om dit aan te vallen, ofwel:
    1. Maak het iteratief . Dat wil zeggen, gebruik for/ whilelussen in plaats van functies die zichzelf - dit mogelijk zou maken voor zo veel knooppunten als uw machines geheugen aankan (het probleem is opgelost).
    2. Update add_name_to_treenaar inserties handgreep voor een gebalanceerde binaire boom (maar dit helpt juist het probleem, de stapel limiet is er nog steeds).
  2. Het kan niet overweg met twee mensen met precies dezelfde naam, maar met verschillende id's - na de eerste persoon wordt toegevoegd aan de boom, alle latere mensen met dezelfde naam worden genegeerd.

Ik laat het als een oefening voor u om deze situaties om te gaan.


#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;
}
antwoordde op 29/05/2011 om 23:46
bron van user

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