coraz winy segmentacji w poszukiwaniu elementu w binarne drzewo poszukiwań w C ++

głosy
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
    }
}

W powyższym programie, tylko przypadek 4 nie działa prawidłowo, gdy próbuję znaleźć konkretny element w drzewie. Mam włączone elementu wyszukiwania funkcji członka na górze głównego programu. Kiedy debugowanie programu, byłem coraz winy segmentacji w funkcji składowej elementu wyszukiwania zwłaszcza jeśli stanie. I naprawdę nie wiem, co muszę zrobić, aby wyjść z tego problemu. Czy ktoś może mi pomóc, aby dowiedzieć się, dlaczego usterka segmentacji dzieje się wewnątrz funkcji Szukaj Użytkownicy elementem. Daj mi znać, jeśli masz jakiekolwiek pytania dotyczące tego programu.

Utwórz 15/04/2011 o 17:23
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
3
if( ((*tree)->data == item) || ( (*tree) == NULL) )

Powinno być

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

Jeśli *treerzeczywiście jest zerowa jesteś dereferencji pustego wskaźnika w pierwszej czeku. Wymieniając je wokół zapewni, że *treenie jest NULL podczas sprawdzania (*tree)->data- ze względu na zwarcie oceny

Dodatkowo, &(*tmp)powinno być napisane jak tylkotmp

Odpowiedział 15/04/2011 o 17:28
źródło użytkownik

głosy
0

Jesteś dereferencing niezainicjowanej wskaźnik (TMP). należy albo przydzielić pamięci dla niego lub po prostu pominąć to wykorzystanie (I naprawdę nie mogę zrozumieć, dlaczego trzeba tymczasowy NODE ** tutaj).

Odpowiedział 15/04/2011 o 17:28
źródło użytkownik

głosy
0

Oto kilka krytyki:
Od szukasz tylko na węźle, nie trzeba wskaźniki do wskaźników. Jedynym razem trzeba wskaźniki do wskaźników to kiedy rzeczywiście trzeba zmodyfikować parametr. Ponadto, ponieważ używasz C ++ zamiast przechodzącą pp, należy podać odniesienie: * & węzła drzewa. To sprawia, że tak można pracować ze zmienną drzewa bez konieczności dereference niego, ponieważ kompilator zajmie to za Ciebie.

W swoim if, nie sprawdzają, jeśli w lewo lub prawo wskaźniki są nieważne wskaźniki. Nie jestem pewien, czy masz wskaźnikowych węzły do ​​tego, ale jestem przy założeniu, że nie. Z tym, chciałbym zmienić metodę do tego:

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
}
Odpowiedział 15/04/2011 o 17:40
źródło użytkownik

głosy
0

Tak. Rzeczywiście, jak już pisał Erik MUSISZ napisać

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

zamiast

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

Bo jeśli itemnie jest już w drzewie kodu z pewnością doprowadzi do wysypać podczas próby wskaźnik nieprawidłowego NULL.

Istnieje również inny (nie tak oczywiste) Problem - absolutnie zbędne rekurencji. Jeśli nie robią staranne wyważenie gdy wkładka lub usunięcia węzłów drzewa można mieć co najwyżej liniowej wysokości drzew, a więc co najwyżej głębokość rekurencji liniowych, które mogą łatwo spowodować przepełnienie stosu. Więc należy przekształcić searchElementfunkcję

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;
}
Odpowiedział 15/04/2011 o 20:37
źródło użytkownik

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