Binäre Suchbaum innerhalb binärer Suchbaum

stimmen
0

Ich habe eine Hausaufgaben, die von mir bitten, eine Struktur von binären Suchbaum zu schaffen, wo seine Knoten des binären Suchbaum eine andere binäre Suchbaum ist. Der erste BST hat die Namen von Studenten und der andere hat die Vornamen und id. Auch wenn jemand hat den gleichen Nachnamen mit einem anderen Studenten muss ich nicht einen anderen „Namen“ Knoten erstellen, aber ich habe in der bestehenden „Nachname“ Knoten einen anderen „Vorname und Id“ Knoten zu erstellen. Um genauer zu sein:

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;

Mein Hauptproblem ist, wie ein anderen nameANDid Knoten für jeden Vornamen erstellen Ich weil mit dem folgenden Code fand ich erstellen 2 BST ein für die Namen und eine andere für die Namen, aber ich würde wie zum Beispiel sein mag: Wenn ich diese Studenten habe

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

Ich möchte, dass sie wie folgt speichern: .........

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

Statt dessen nehme ich etwas wie: ...........

 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

Ich werde einige Funktionen in Ordnung bringen hier genauer zu sein

Die Ladefunktion lädt die Namen aus einem txt-Dokument.

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

woher

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

Die addnode Funktion ist: ...

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

Und die add_node_nameANDid () Funktion ist wie die vorherige Funktion, aber es hat einige Variablen geändert:

      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 für die riesige Quellcode, ich lade gerade, aber es wäre sehr schwierig sein, ohne dass dies zu erklären.

Ich denke, dass ich habe zwei Probleme, aber ich habe nicht das Wissen, sich zu lösen.

FIRST: muß ich für jeden Nachnamen Knoten unterschiedlichen Vornamen BST erstellen, und ich denke, dass ich das nicht tun, aber ich weiß nicht, wie das zu tun ...

Irgendwelche Vorschläge?

Veröffentlicht am 29/05/2011 um 12:22
quelle vom benutzer
In anderen Sprachen...                            


1 antworten

stimmen
2

Ich habe eine Beispielimplementierung dieses weiter unten, kommentiert zu erklären, wie ich das angesprochen. Sie sollten meine Ideen der Lage sein, zu verwenden, um die Art und Weise Ihr Code funktioniert zu ändern. Beachten Sie, dass es nicht eine perfekte Umsetzung, aus der Spitze von meinem Kopf, ich die folgenden Probleme sehen.

  1. Seine rekursiven , welche die Tiefe des Baumes bedeutet es verarbeiten kann , sind durch die Größe des Stapels auf der Zielmaschine begrenzt. Es gibt zwei Möglichkeiten , wie Sie diese angreifen kann, entweder:
    1. Machen Sie es iterative . Das heißt, die Verwendung for/ whileSchleifen statt Funktionen selbst nennen - dies für so viele Knoten erlauben würde , als Maschinen - Speicher umgehen kann (behebt das Problem).
    2. Update add_name_to_treezu behandeln Einfügungen für einen ausgewogenen binären Baum (aber das hilft nur das Problem, ist die Stapelgrenze immer noch da).
  2. Es kann nicht zwei Personen mit genau dem gleichen Namen behandeln, aber unterschiedliche IDs - nachdem die erste Person zu dem Baum hinzugefügt wird, wird alle nachfolgenden Personen mit dem gleichen Namen ignoriert werden.

Ich werde es als eine Übung für Sie hinterlassen, diese Situationen zu handhaben.


#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;
}
Beantwortet am 29/05/2011 um 23:46
quelle vom benutzer

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