Δυαδική Αναζήτηση δέντρο μέσα Δυαδική Αναζήτηση δέντρο

ψήφοι
0

Έχω ένα σπίτι που ζητούν από μένα για να δημιουργήσετε ένα struct του δυαδικού δένδρου αναζήτησης, όπου ο κόμβος του δυαδικού δένδρου αναζήτησης είναι ένα άλλο δυαδικό δένδρο αναζήτησης. Η πρώτη BST έχει τα επώνυμα των Φοιτητών και ο άλλος έχει τα πρώτα ονόματα και ταυτότητα. Επίσης, αν κάποιος έχει το ίδιο επώνυμο με ένα άλλο μαθητή δεν πρέπει να δημιουργήσει ένα άλλο «επώνυμο» κόμβος, αλλά έχω να δημιουργήσουν μέσα στο υπάρχον κόμβο «επώνυμο» άλλο «όνομα και ταυτότητα» του κόμβου. Για να γινω πιο συγκεκριμενη:

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;

κύριο πρόβλημά μου είναι πώς να δημιουργήσετε ένα διαφορετικό κόμβο nameANDid για κάθε firstname βρήκα γιατί με τον κωδικό μπορώ να δημιουργήσω 2 ένα BST για τα επώνυμα και ένα άλλο για τα ονόματα, αλλά θα ήθελα να είναι όπως, για παράδειγμα: Αν έχω αυτούς τους φοιτητές

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

Θέλω να τα αποθηκεύσετε ως εξής: .........

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

Αντί γι 'αυτό παίρνω κάτι σαν: ...........

 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

Θα βάλω εδώ μερικές λειτουργίες για να γίνω πιο συγκεκριμένος

Η λειτουργία του φορτίου φορτώνει τα ονόματα από ένα έγγραφο 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

Η λειτουργία 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;
         }

Και η add_node_nameANDid () συνάρτηση είναι σαν την προηγούμενη λειτουργία, αλλά έχει κάποιες μεταβλητές αλλάξει:

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

Συγγνώμη για το τεράστιο πηγαίο κώδικα που μόλις φορτώσετε αλλά θα ήταν πολύ δύσκολο να εξηγήσουμε χωρίς αυτό.

Νομίζω ότι έχω δύο προβλήματα, αλλά δεν έχω τις γνώσεις για την επίλυσή τους.

ΠΡΩΤΟ: Πρέπει να δημιουργήσετε διαφορετικά firstname BST για κάθε κόμβο επώνυμο και νομίζω ότι δεν το κάνουμε αυτό, αλλά δεν ξέρω πώς να το κάνουμε αυτό ...

Οποιεσδήποτε προτάσεις?

Δημοσιεύθηκε 29/05/2011 στις 12:22
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
2

Έχω δώσει ένα παράδειγμα εφαρμογής αυτού παρακάτω, σχολίασε να εξηγήσει πώς προσέγγισε αυτό. Θα πρέπει να είναι σε θέση να χρησιμοποιούν τις ιδέες μου για να τροποποιήσετε τον τρόπο με τον κωδικό σας λειτουργεί. Σημειώστε ότι δεν είναι μια τέλεια εφαρμογή του, από την κορυφή του κεφαλιού μου, μπορώ να δω τα ακόλουθα προβλήματα.

  1. Της επαναληπτικής , το οποίο σημαίνει ότι το βάθος του δέντρου μπορεί να χειριστεί περιορίζεται από το μέγεθος της στοίβας στο μηχάνημα-στόχο. Υπάρχουν δύο τρόποι για να επιτεθούν αυτό, είτε:
    1. Κάντε το επαναληπτικό . Δηλαδή, η χρήση for/ whileβρόχους, αντί να λειτουργεί καλώντας τον εαυτό τους - αυτό θα επιτρέψει για όσες κόμβους ως μηχανές μνήμη σας μπορεί να χειριστεί (διορθώνει το πρόβλημα).
    2. Ενημέρωση add_name_to_treeγια να χειριστεί προσθήκες για μια ισορροπημένη δυαδικό δέντρο (αλλά αυτό βοηθά μόνο το θέμα, το όριο στοίβα είναι ακόμα εκεί).
  2. Δεν μπορεί να χειριστεί δύο ανθρώπους με το ίδιο ακριβώς όνομα, αλλά διαφορετικό id του - μετά το πρώτο πρόσωπο που προστίθεται στο δέντρο, όλες οι επόμενες ανθρώπους με το ίδιο όνομα αγνοούνται.

Θα το αφήσουμε ως μια άσκηση για να χειριστεί αυτές τις καταστάσεις.


#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;
}
Απαντήθηκε 29/05/2011 στις 23:46
πηγή χρήστη

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