ottenendo segmentation fault nella ricerca di un elemento in albero binario di ricerca in C ++

voti
1
node ** BST :: searchElement(node **tree, int item)
{
    if( ((*tree)->data == item) || ( (*tree) == NULL) )
        return tree;
    else if( item < (*tree)->data)
        return searchElement( &(*tree)->left, item);
    else
       return searchElement( &(*tree)->right, item);
}

int main(){
    BST obj;
    int choice;
    int height=0,total=0,n,item;
    node **tmp;
    system(cls);

    while(1){
        //clrscr();
        cout<<*****BINARY SEARCH TREE OPERATIONS*****\n\n;
        cout<<1) Create Tree\n;
        cout<<2) Traversal\n;
        cout<<3)  Insert Node\n;
        cout<<4)  Search Node\n;
        cout<<5 Find Smallest Node\n;
        cout<<6) Find Largest Node\n;
        cout<<7) Exit\n;
        cout<<Enter your choice : ;
        cin>>choice;
        switch(choice){
            case 1 : //Create Tree
                cout<<\n\n--Creating Tree--;
                cout<<\nHow many nodes u want to enter : ;
                cin>>n;
                for(int i=0;i<n;i++){
                    cout<<Enter value : ;
                    cin>>item;
                    obj.createTree(&obj.tree,item);
                }
                break;

            case 2 : //All Traversals
                cout<<\n\nInorder Traversal : ;
                obj.inOrder(obj.tree);

                cout<<\n\nPre-order Traversal : ;
                obj.preOrder(obj.tree);

                cout<<\n\nPost-order Traversal : ;
                obj.postOrder(obj.tree);
                getch();
                break;

            case 3 : //Inserting a node in a tree
                cout<<\n\n--Inserting Node in a tree--\n;
                cout<<Enter value : ;
                cin>>item;
                obj.createTree(&obj.tree,item);
                cout<<\nItem is inserted\n;
                getch();
                break;

            case 4 : //Search element
                cout<<\n\n--Search Element--\n;
                cout<<Enter item to searched : ;
                cin>>item;
                &(*tmp) = obj.searchElement(&obj.tree,item);
                if( (*tmp) == NULL)
                cout<<\nSearch Element was not Found;
                else
                    cout<<\nSearch Element was Found;
                getch();
                break;
            case 5 : //Find Smallest Node
                cout<<\n\nSmallest Node is :  ;
                obj.findSmallestNode(obj.tree);
                getch();
                break;

            case 6 : //Find Largest Node
                cout<<\n\nLargest Node is :  ;
                obj.findLargestNode(obj.tree);
                getch();
                break;



            case 7: exit(1);
        }//end of switch
    }
}

Nel programma precedente, unico caso 4 non funziona correttamente quando si tenta di trovare l'elemento particolare albero. Ho incluso la funzione di membro elemento di ricerca nella parte superiore del programma principale. Quando mi è stato Debug del programma, mi è stato sempre segmentation fault nella funzione membro elemento di ricerca soprattutto in se la condizione. Io davvero non so che cosa devo fare per uscire da questo problema. Qualcuno può aiutarmi a scoprire perché segmentation fault sta accadendo all'interno funzione di ricerca membro elemento. Fatemi sapere se avete qualsiasi domanda riguardante questo programma.

È pubblicato 15/04/2011 alle 17:23
fonte dall'utente
In altre lingue...                            


4 risposte

voti
3
if( ((*tree)->data == item) || ( (*tree) == NULL) )

Dovrebbe essere

if ( ( (*tree) == NULL) || ((*tree)->data == item) )

Se *treein realtà è nulla che stai dereferenziazione un puntatore nullo nel primo controllo. Scambiando loro intorno farà in modo che *treenon è nullo quando si controlla (*tree)->data- a causa di valutazione di corto circuito

Inoltre, &(*tmp)dovrebbe essere scritto come solotmp

Risposto il 15/04/2011 a 17:28
fonte dall'utente

voti
0

Stai dereferenziazione un puntatore non inizializzato (tmp). Si dovrebbe sia allocare memoria per esso o semplicemente saltare è l'uso (io davvero non riesco a capire il motivo per cui è necessario un nodo temporanea ** qui.)

Risposto il 15/04/2011 a 17:28
fonte dall'utente

voti
0

Qui ci sono un paio di critiche:
Dal momento che si sta cercando solo per un nodo, non è necessario puntatori-a-puntatori. L'unica volta che è necessario puntatori a puntatori sono quando è effettivamente necessario per modificare il parametro. Inoltre, dal momento che si sta utilizzando C ++, invece di passare un PP, si dovrebbe passare un riferimento: il nodo * & albero. Questo lo rende in modo da poter lavorare con la variabile di albero senza dover dereferenziarlo, dal momento che il compilatore si prenderà cura di questo per voi.

Nei tuoi if, che non sta verificando se i puntatori a destra oa sinistra sono puntatori nulli. Non sono sicuro se si dispone di linfonodo sentinella per questo, ma sto assumendo che tu non lo fai. Con questo, vorrei cambiare il metodo a questo:

node * BST :: searchElement(node *tree, int item)
{
    if(tree->data == item)
        return tree;
    //short circuit if statements
    else if( (tree->left != NULL) && (item < tree->data) )
        return searchElement( tree->left, item );
    else if( (tree->right != NULL) && (item > tree->data) ) //>= for duplicates
        return searchElement( tree->right, item );

    return NULL; //if it isn't found
}
Risposto il 15/04/2011 a 17:40
fonte dall'utente

voti
0

Sì. Infatti, come già pubblicato Erik è necessario scrivere

if ( ( (*tree) == NULL) || ((*tree)->data == item) )

invece di

if( ((*tree)->data == item) || ( (*tree) == NULL) )

Perché se itemnon è già in un albero vostro codice sarà sicuramente portare a segmentation fault quando si cerca di puntatore nullo.

C'è anche un altro (non così ovvio) problema - assolutamente ricorsione non necessaria. Se non stai facendo attento bilanciamento quando si inserisce o si rimuove i nodi dell'albero, dovete al massimo l'altezza degli alberi lineari e quindi al massimo la profondità di ricorsione lineare che può facilmente portare a impilare troppo pieno. Così si dovrebbe trasformare searchElementla funzione di

node** BST::searchElement( node** tree, int item )
{
    while(  ( (*tree) != NULL)  &&  ( (*tree)->data != item )  )
    {
        if( item < (*tree)->data )
        {
            tree = &(*tree)->left;
        }
        else
        {
            tree = &(*tree)->right;
        }
    }

    return tree;
}
Risposto il 15/04/2011 a 20:37
fonte dall'utente

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