İkili Arama ağacın içinde İkili Arama ağaç

oy
0

Ben ikili arama ağacının onun düğüm başka bir ikili arama ağacı nerede ikili arama ağacının bir yapı oluşturmak için benden rica bir ödev var. İlk BST Öğrenci Soyadlarını vardır ve diğeri birinci isim ve kimliğine sahip olacaktır. Birisi başka bir soyadı düğümünü yaratmamalıdır başka bir öğrenci ile aynı soyadı var ama ben mevcut soyadı düğüm içinde başka ad ve İd düğüm oluşturmak zorunda Ayrıca eğer. Daha spesifik olmak gerekirse:

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;

Ben bu öğrencilerin varsa: Benim asıl sorun ben adları için 2 BST soyadı için ve başka oluşturmak ama örneğin gibi olmak istiyorum ben aşağıdaki kodla çünkü bulunan her firstname için farklı nameANDid düğümü oluşturmak için nasıl

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

Böyle bunları saklamak istiyorum: .........

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

Bunun yerine ben böyle bir şey almak: ...........

 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

Daha spesifik olmak için buraya bazı fonksiyonlarını koyacağız

Yük işlevi, bir txt belgesinden isimleri yükler.

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

nerede

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

AddNode fonksiyonudur: ...

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

Ve add_node_nameANDid () işlevi, önceki fonksiyonu gibidir ancak bazı değişkenler değişti vardır:

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

Sadece yüklemek ama bu olmadan açıklamak çok zor olacaktır dev kaynak kodu için üzgünüm.

Ben iki sorun var ama bunları çözmek için bilgiye sahip olmadığını düşünüyorum.

İLK: Her soyadı düğüm için farklı ad BST oluşturmak zorunda ve ben bunu yapmam düşünüyorum ama bunu nasıl bilmiyorum ...

Baska öneri?

Oluştur 29/05/2011 saat 12:22
kaynak kullanıcı
Diğer dillerde...                            


1 cevaplar

oy
2

Bunu nasıl yaklaştığını açıklamaya yorumladı aşağıda bunun bir örneğidir uygulanmasını verdik. Eğer kod çalışma şeklini değiştirmek için fikirlerimi kullanmak gerekir. Kafamın üst kapalı onun değil mükemmel uygulama, aşağıdaki sorunlara görebileceğinizi unutmayın.

  1. Bu yinelemeli işleyebilir ağacın dinamik anlamına gelir, hedef makinede yığının boyutu ile sınırlıdır. Sen de bu saldırabilir iki yolu vardır:
    1. O Make iteratif . Yani kullanımı olup for/ whileyerine kendilerini çağıran fonksiyonların döngüler - işleyebilir makineler hafıza (sorununu giderir) bu kadar çok düğümler için izin verecek.
    2. Güncelleme add_name_to_treebir için eklemeleri işlemek için dengeli ikili ağacın (ama bu sadece konuyu yardımcı olur, yığın sınırı hala orada).
  2. Tam olarak aynı adı taşıyan iki kişiyi işleyemez, ancak farklı id en - ilk insan ağacına eklendikten sonra, aynı adı taşıyan sonraki tüm insanlar dikkate alınmaz.

Bu durumları ele almak için bir alıştırma olarak bırakacağım.


#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;
}
Cevap 29/05/2011 saat 23:46
kaynak kullanıcı

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