Pregunta

¿Qué hay de malo en la siguiente implementación de un árbol binario de búsqueda (BST) ? Me han dicho que es mejor usar puntero a un puntero a struct nodo como un argumento en función de inserción.

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 );
    }
}
¿Fue útil?

Solución

Esta línea:

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

da un nuevo valor a leaf, apuntando a algo de memoria recién asignada. Sin embargo, el nuevo valor no sale de la función. Cuando la función devuelve, la persona que llama todavía se refería a la vieja leaf, y habrá una pérdida de memoria.

Hay dos enfoques que se pueden tomar a la fijación de él:

1. utilizar un puntero a un puntero, por ejemplo.

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. Vuelta la nueva hoja (o la edad de la hoja si no hay ningún cambio).

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

Los punteros a punteros están cerca del umbral de ser difícil de comprender. Yo probablemente vaya por la segunda opción, si insert actualmente no está regresando otra cosa.

Otros consejos

Cuando se inserta un nodo (hoja == 0), que no cambió su matriz, por lo que el nuevo nodo se convertirá en un huérfano.

En otras palabras, el árbol será tener la apariencia de un solo nodo, no importa cuántos nodos se llama con parte.

  #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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top