在 c++ 中搜索二叉搜索树中的元素时出现分段错误

发布于 2024-11-01 15:39:29 字数 3165 浏览 1 评论 0原文

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

在上面的程序中,当我尝试在树中查找特定元素时,只有情况 4 无法正常工作。我在主程序的顶部包含了搜索元素成员函数。当我调试程序时,我在搜索元素成员函数中遇到分段错误,尤其是在 if 条件中。我真的不知道我需要做什么才能摆脱这个问题。谁能帮我找出搜索元素成员函数内部发生分段错误的原因。如果您对此计划有任何疑问,请告诉我。

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

In the above program, only case 4 is not working correctly when I try to find the particular element in tree. I have included search element member function on the top of the main program. When I was debugging program, I was getting segmentation fault in search element member function especially in if condition. I really don't know what I need to do to come out of this problem. Can anyone please help me to find out why segmentation fault is happening inside search element member function. Let me know if you have any questions regarding this program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

堇年纸鸢 2024-11-08 15:39:29
if( ((*tree)->data == item) || ( (*tree) == NULL) )

应该是

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

如果*tree实际上 null,则您在第一次检查中取消引用空指针。交换它们将确保当您检查 (*tree)->data*tree 不为 NULL - 由于 短路评估

此外,&(*tmp) 应写为 tmp

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

Should be

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

If *tree actually is null you're dereferencing a null pointer in the first check. Swapping them around will ensure that *tree isn't NULL when you check (*tree)->data - due to Short Circuit Evaluation

Additionally, &(*tmp) should be written as just tmp

纸短情长 2024-11-08 15:39:29

您正在取消引用未初始化的指针(tmp)。你应该为它分配内存或者跳过它的使用(我真的不明白为什么你需要一个临时节点**。)

You're dereferencing an uninitialized pointer (tmp). You should either allocate memory for it or just skip it's usage (I really can't figure out why you need a temporary NODE** here.)

握住我的手 2024-11-08 15:39:29

以下是一些批评:
由于您只搜索节点,因此不需要指针到指针。唯一需要指向指针的指针是当您实际需要修改参数时。另外,由于您使用的是 C++,因此您应该传递引用:node * &tree,而不是传递 pp。这使得您可以使用树变量而无需取消引用它,因为编译器会为您处理这个问题。

在 if 语句中,您不会检查左指针或右指针是否为空指针。我不确定你是否有这方面的哨兵节点,但我假设你没有。这样,我会将您的方法更改为:

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
}

Here are a couple critiques:
Since you are only searching for a node, you don't need pointers-to-pointers. The only time you need pointers to pointers are when you actually need to modify the parameter. Also, since you are using C++, instead of passing a pp, you should pass a reference: node * &tree. This makes it so you can work with the tree variable without having to dereference it, since the compiler will take care of that for you.

In your if statements, you aren't checking if your left or right pointers are null pointers. I'm not sure if you have sentinel nodes for this, but I'm assuming you don't. With that, I would change your method to this:

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
}
ヅ她的身影、若隐若现 2024-11-08 15:39:29

是的。事实上,正如 Erik 已经发布的那样,您必须编写

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

Yes. Indeed as Erik already posted you MUST write

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

instead of

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

Because if item is not already in a tree your code will DEFINITELY lead to segfault when trying to dereference NULL pointer.

There is also another (not so obvious) problem - absolutely unnecessary recursion. If you are not doing careful balancing when insert or remove tree nodes you will have at most linear tree height and thus at most linear recursion depth that may easily lead to stack overflow. So you should transform searchElement function to

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文