získávání segmentation fault při hledání prvek v binárním vyhledávacím stromu v C ++

hlasů
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
    }
}

Ve výše uvedeném programu, jediný případ 4 nefunguje správně, když se snaží najít určitý prvek stromu. Zahrnul jsem členské funkce vyhledávání prvku v horní části hlavního programu. Když jsem byl ladění programu, byl jsem dostat chybu segmentace na členské funkce vyhledávání element, zejména v případě, stavu. Já opravdu nevím, co musím udělat, aby vyšel z tohoto problému. Mohl by někdo prosím, pomozte mi zjistit, proč se chyba segmentace děje uvnitř hledání element členské funkce. Dejte mi vědět, pokud máte jakékoliv dotazy týkající se tohoto programu.

Položena 15/04/2011 v 17:23
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

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

Mělo by

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

Pokud *treeve skutečnosti je null jste dereferencing null ukazatel na první kontrole. Odkládání kolem nich se zajistí, že *treenení NULL při kontrole (*tree)->data- v důsledku zkrácené vyhodnocování

Kromě toho &(*tmp)by měla být zapsána jentmp

Odpovězeno 15/04/2011 v 17:28
zdroj uživatelem

hlasů
0

Jsi dereferencing neinicializované ukazatel (TMP). Měli byste buď přidělit paměť pro to, nebo jen přeskočit to je využití (opravdu nemůžu přijít na to, proč je třeba dočasné NODE ** zde.)

Odpovězeno 15/04/2011 v 17:28
zdroj uživatelem

hlasů
0

Zde je pár kritiky:
Vzhledem k tomu, hledáte jen pro uzel, nemusíte ukazatelů k ukazateli. Jediný okamžik, kdy je třeba odkazy na ukazateli jsou, když ve skutečnosti je třeba změnit parametr. Také, protože se v jazyce C ++, namísto předání PP, měli předat odkaz: uzel * & strom. To dělá to, takže můžete pracovat s stromu proměnné, aniž by museli dereference ní, protože překladač bude postarat se o to pro vás.

Ve svých if, že nejste se podívejte, zda levý nebo pravý kanál ukazatele jsou ukazatele null. Nejsem si jistý, jestli máte sentinelových uzlin k tomuto účelu, ale já jsem za předpokladu, že ne. S tím bych změnit svůj způsob, jak to:

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
}
Odpovězeno 15/04/2011 v 17:40
zdroj uživatelem

hlasů
0

Ano. Ve skutečnosti, jak Erik již zaslali musíte zadávat

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

namísto

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

Vzhledem k tomu, pokud itemjiž není na stromě váš kód bude určitě povede k segfault při pokusu o dereference ukazatel NULL.

Tam je také další (ne tak zřejmé) problém - naprosto zbytečné rekurze. Pokud nejste dělat pečlivé vyvažování při vložení nebo odebrání uzly stromu, budete mít maximálně lineární výšky stromu, a tak maximálně lineární hloubku rekurze, které mohou snadno vést k přetečení zásobníku. Takže byste měli transformovat searchElementfunkci

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;
}
Odpovězeno 15/04/2011 v 20:37
zdroj uživatelem

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