получать ошибки сегментации при поиске элемента в бинарном дереве поиска в C ++

голоса
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
    }
}

В приведенной выше программе, только случай-не работает правильно, когда я пытаюсь найти определенный элемент в дереве. Я включил функцию члена поиска элемента в верхней части основной программы. Когда я отладки программы, я получаю ошибку сегментации в функции члена поиска элемента особенно если условия. Я действительно не знаю, что мне нужно сделать, чтобы выйти из этой проблемы. Может кто-нибудь, пожалуйста, помогите мне, чтобы выяснить, почему ошибка сегментации происходит внутри функции поиска члена элемента. Дайте мне знать, если у вас есть какие-либо вопросы относительно этой программы.

Задан 15/04/2011 в 17:23
источник пользователем
На других языках...                            


4 ответов

голоса
3
if( ((*tree)->data == item) || ( (*tree) == NULL) )

Должно быть

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

Если на *treeсамом деле является нулевым вы разыменования нулевого указателя в первой проверки. Обменивать их вокруг будет гарантировать , что *treeне NULL при проверке (*tree)->data- из - за Короткое замыкание оценки

Кроме того, &(*tmp)должно быть написано , как толькоtmp

Ответил 15/04/2011 в 17:28
источник пользователем

голоса
0

Вы разыменование неинициализированного указателя (TMP). Вы должны либо выделить память для него или просто пропустить его использование (я действительно не могу понять, почему вам нужен временный УЗЕЛ ** здесь.)

Ответил 15/04/2011 в 17:28
источник пользователем

голоса
0

Вот пара критики:
Поскольку вы ищете только для узла, вам не нужны указатели к указателям. Единственный раз , когда вам нужны указатели на указатели, когда вы на самом деле нужно изменить параметр. Кроме того , так как вы используете C ++, вместо того , чтобы передать п.п., вы должны передать ссылку: узел * & дерево. Это делает его таким образом , вы можете работать с переменным деревом без разыменования его, так как компилятор будет заботиться о том , что для вас.

В вашем если заявления, вы не проверить, если ваши левые или правые указатели являются нулевые указатели. Я не уверен, если у вас есть дозорные узлы для этого, но я предполагаю, что вы не делаете. При том, что я хотел бы изменить свой метод следующим образом:

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
}
Ответил 15/04/2011 в 17:40
источник пользователем

голоса
0

Да. На самом деле, как Эрик уже отправил вы должны написать

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

вместо

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

Потому что , если itemэто уже не в дереве код, безусловно , приведет к сегментации при попытке указателя разыменования NULL.

Существует и другая (не так очевидно) проблема - абсолютно ненужная рекурсия. Если вы не делаете тщательную балансировку , когда вставка или удаления узлов дерева вы будете иметь в большей линейной высоту дерева и , следовательно , в большей линейной глубине рекурсии , которая может легко привести к переполнению стека. Таким образом , вы должны преобразовать searchElementфункцию

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;
}
Ответил 15/04/2011 в 20:37
источник пользователем

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