implementazione BST

voti
1

Cosa c'è di sbagliato con la seguente implementazione di un albero binario di ricerca (BST) ? Mi è stato detto che è meglio usare il puntatore a un puntatore a structnodo come argomento nella funzione di inserimento.

struct node
{
int key_value;
struct node* left;
struct node* right;
};

insert(int key, struct node *leaf)
{
    if( leaf == 0 )
    {
        leaf = (struct node*) malloc( sizeof( struct node ) );
        leaf->key_value = key;
        /* initialize the children to null */
        leaf->left = 0;    
        leaf->right = 0;  
    }
    else if(key < leaf->key_value)
    {
        insert( key, leaf->left );
    }
    else if(key > leaf->key_value)
    {
        insert( key, leaf->right );
    }
}
È pubblicato 13/01/2010 alle 11:01
fonte dall'utente
In altre lingue...                            


3 risposte

voti
1

Quando un nodo viene inserito (foglia == 0), non ha modificato il suo genitore, in modo che il nuovo nodo diventerà un orfano.

In altre parole, il vostro albero sarà ancora l'aspetto di un solo nodo, indipendentemente dal numero di nodi sono stati chiamati con inserto.

Risposto il 13/01/2010 a 12:32
fonte dall'utente

voti
2

Questa linea:

leaf = (struct node*) malloc( sizeof( struct node ) );

dà un nuovo valore leaf, puntando ad un certo memoria appena allocata. Tuttavia, il nuovo valore non lascia la funzione. Quando la funzione ritorna, il chiamante sarà ancora riferimento al vecchio leaf, e ci sarà una perdita di memoria.

Ci sono due approcci si potrebbe adottare per risolverlo:

1. Utilizzare un puntatore a un puntatore, ad esempio,

void insert(int key, struct node **leaf)
{
    if(*leaf == 0 )
    {
        *leaf = (struct node*) malloc( sizeof( struct node ) );
        ...
}

/* In caller -- & is prepended to current_leaf. */
insert(37, &current_leaf);

2. Riportare la nuova foglia (o il vecchio foglia se non v'è nessun cambiamento).

struct node *insert(int key, struct node *leaf)
{
    if(leaf == 0 )
    {
        leaf = (struct node*) malloc( sizeof( struct node ) );
        ...
    }

    return leaf;
}

/* In caller -- & is prepended to current_leaf. */
current_leaf = insert(37, current_leaf);

Puntatori a puntatori sono vicino alla soglia di essere difficile da comprendere. Io probabilmente andare per la seconda opzione, se insertal momento non è tornare ogni altra cosa.

Risposto il 13/01/2010 a 12:48
fonte dall'utente

voti
-2
  #include<stdio.h>
     typedef struct tnode{
       int data;
       struct tnode *left,*right;
     }TNODE;
     TNODE * createTNode(int key){
       TNODE *nnode;
       nnode=(TNODE *)malloc(sizeof(TNODE));    
       nnode->data=key;
       nnode->left=NULL;
       nnode->right=NULL;
      return nnode;
}

    TNODE * insertBST(TNODE *root,int key){
     TNODE *nnode,*parent,*temp;
     temp=root;
      while(temp){
        parent=temp;
        if(temp->data > key)
            temp=temp->left;
        else
            temp=temp->right;    
    }    
     nnode=createTNode(key);
    if(root==NULL)
        root=nnode;
    else if(parent->data>key)
        parent->left=nnode;
    else
        parent->right=nnode;
    return root;
}

     void preorder(TNODE *root){
       if(root){
         printf("%5d",root->data);    
         preorder(root->left);
         preorder(root->right);
       }    
     }  

    void inorder(TNODE *root){
       if(root){
        inorder(root->left);
        printf("%5d",root->data);    
        inorder(root->right);
      }    
    }

    void postorder(TNODE *root){
       if(root){
        postorder(root->left);    
        postorder(root->right);
        printf("%5d",root->data);
      }    
    }

     main(){
       TNODE *root=NULL;
       int ch,key;
       do{
         printf("\n\n1-Insert\t2-Preorder\n3-Inorder\t4-Postorder\n5-Exit\n");
         printf("Enter Your Choice: ");
         scanf("%d",&ch);  

        switch(ch){ 
            case 1:
                printf("Enter Element: ");
                scanf("%d",&key);
                root=insertBST(root,key);
                break;
            case 2:
                preorder(root);
                break;
            case 3:
                inorder(root);
                break;
            case 4:
                postorder(root);
                break;
            default:
                printf("\nWrong Choice!!");
        }

    }while(ch!=5);
    getch();
    return 0;
}
Risposto il 04/10/2013 a 14:31
fonte dall'utente

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