为什么这个二叉搜索树会导致堆栈溢出

Why does this binary search tree cause a stack overflow?

本文关键字:堆栈 栈溢出 搜索树 为什么      更新时间:2023-10-16
#include<iostream>
using namespace std;
/*main  idea  is to construct ordered statistic tree,which is  similar of
binary search tree,width addition of  one key,which shows us it's rank in given  
tree,for this i introduced additional one key-rank
*/
struct node
{
    int val;
    node *left,*right;
    int rank;
    node(int t) { val=t;left=right=NULL;}

};
node *root;
void insert(node *p,int ele)
{
    if(p==NULL){
        p=new node(ele);
        return ;

    }
    else if(ele<p->val)
    {
        insert(p->left,ele);
    }
    else if(ele>p->val)
    {
        insert(p->right,ele);
    }
}
void inorder (node *p)
{
    if(p!=NULL){ inorder(p->left);
    cout<<p->val<<" "<<p->rank;
    inorder(p->right);
    }
}
int count_node(node *t)
{
    int sum=0;
    if(t==NULL) return 0;
    else sum=1;
    if(t->left) sum+=count_node(t->left);
    if(t->right) sum+=count_node(t->right);
    return sum;
}
int main()
{
    root=NULL;
    root->rank=0;
    insert(root,26);
    insert(root,17);
    insert(root,41);
    insert(root,14);
    insert(root,30);
    insert(root,21);
    insert(root,47);
    insert(root,10);
    insert(root,16);
    insert(root,28);
    insert(root,38);
    insert(root,35);
    insert(root,39);
    insert(root,19);
    insert(root,21);
    insert(root,20);
    insert(root,7);
    insert(root,12);
    insert(root,3);
    inorder(root);
    return 0;
}

这段代码会导致溢出,但我不明白为什么,因为我已经正确地构造了构造函数。

问题是:

root=NULL;
root->rank=0;

这会导致未定义的行为,因为您取消引用NULL指针。任何事情都可能发生。

也:

void insert(node *p,int ele)
{
    if(p==NULL){
        p=new node(ele);
        return ;

    }
    //...
}

这不会修改原始指针。如果在 NULL 指针上调用 insert,则函数返回时将NULL该指针。您需要通过引用传递它:

void insert(node *& p,int ele)

除了Luchian说的,你还有这个问题:

void insert(node *p,int ele)
{
    if(p==NULL){
        p=new node(ele);
        return ;
    }
....

其中指针p按值传递。当您说p=...时,您正在更改仅对函数可见的指针副本。您可能需要对要更改的指针的引用:

void insert(node *&p, int ele){ ... }

main函数的前两行有一个非常大的问题:

root=NULL;
root->rank=0;

如果您查看上面的定义,root被定义为节点指针,也就是说,它不会为实际节点保留任何空间。

如果您自己不保留空间,则尝试通过未初始化的内存进行写入。更重要的是,你明确说根指向什么都没有,那就是NULL.在下一行中,您尝试访问它的成员,称为 rank .

您应该尝试替换以下行:

root = NULL;

root = new node(0);

或类似的东西,实际保留空间并构造一个节点。

或者,您可以尝试在最后将秩断言为根,因为如果根不存在,您insert函数实际上构造了根。编辑 正如Luchian所说,您只尝试insert方法中构造根。如果您按照他建议的方式重写插入方法,那么如果您只是将root->rank=0;行移动到插入过程的末尾,它可能都可以工作。

root=NULL;
root->rank=0;

这可能是问题所在,您不应该尊重NULL对象。