简体   繁体   English

C ++中的二进制搜索树

[英]Binary Search Tree in C++

I'm learning C++ language and I'm trying to write BST, but something goes wrong. 我正在学习C ++语言而且我正在尝试编写BST,但出了点问题。 I try to add element to empty tree, root is NULL, but after adding element root is still NULL despite of the fact that addiing was successful (I saw it in debug mode, node is set as tmp). 我尝试将元素添加到空树中,root为NULL,但是尽管添加成功(尽管我在调试模式下将其设置为tmp),但添加元素后root仍然为NULL。 I have no idea why it happens. 我不知道为什么会这样。

struct Node
{
    int data;
    Node* left;
    Node* right;
};

struct Tree
{
    Node* root;
};

Tree createTree()
{
    Tree tmp;
    tmp.root = NULL;
    return tmp;
}

void addToNode(Node* node, int value)
{
    Node* tmp = new Node;
    tmp->data = value;
    tmp->left = NULL;
    tmp->right = NULL;
    if(node == NULL)
        node = tmp;
    else if(value >= node->data)
        addToNode(node->right, value);
    else
        addToNode(node->left, value);
}

void add(Tree* tree, int value)
{
    addToNode(tree->root, value);
}

int _tmain(int argc, _TCHAR* argv[])
{
    Tree tree = createTree();
    add(&tree, 10);
    printf("%d", tree.root->data);
    scanf("%*s");
    return 0;
}

In the function addToNode when you assign to node , that assignment is not visible in the function calling addToNode because node is a local variable. 在分配给node的函数addToNode ,该调用在调用addToNode的函数中不可见,因为node是一个局部变量。

You should pass it as a reference instead: 您应该将其作为参考传递:

void addToNode(Node*& node, int value)
{
    ...
}

When you are passing your pointer into the function, you create a local version of the pointer. 将指针传递给函数时,将创建指针的本地版本。 This local variable ( node ) does indeed point into the same memory that the outer pointer you were passing. 实际上,此局部变量( node )确实指向与您传递的外部指针相同的内存。 However, any attempt to change this variable ( not the memory it points to, but the pointer variable itself) will only change the local variable. 但是,任何更改此变量的尝试( 不是它指向的内存,而是指针变量本身)都只会更改局部变量。

So your node points to the same memory location as your tree , but the node variable itself isn't equal to the tree variable, so your changes are not visible from the outer function. 因此,您的node指向与tree相同的内存位置,但是node变量本身不等于tree变量,因此您的更改在外部函数中不可见。

It sounds complicated, sorry, but it's exacly the same thing as in this: 听起来很复杂,很抱歉,但与此完全一样:

void foo( int a )
{
    a++;
}
int main()
{
    int var = 5;
    foo( var );
    std::cout << var;
}

Of course in this case the var will not change, it's the a that is being changed inside the function. 当然,在这种情况下, var也不会改变,这是a正在被在函数内部改变。

To fix the issue, pass a reference to the pointer instead of the pointer itself: 要解决此问题,请将引用传递给指针而不是指针本身:

void addToNode(Node*& node, int value)

Joachim already beat me to the answer, but I'll add this observation in anyway. 约阿希姆(Joachim)早已击败了我,但无论如何我都会添加这个观察结果。

Your code leaks memory. 你的代码泄漏了内存。

void addToNode(Node* node, int value)
{
    Node* tmp = new Node;
    tmp->data = value;
    tmp->left = NULL;
    tmp->right = NULL;
    if(node == NULL)
        node = tmp;
    else if(value >= node->data)
        addToNode(node->right, value);
    else
        addToNode(node->left, value);
}

Every call to addToNode creates a new Node instance in tmp , but if the parameter Node* node is not NULL , this new Node is not deleted and does not become accessible by the rest of the application. 每次调用addToNode都会在tmp创建一个新的Node实例,但是如果参数Node* node不是NULL ,则不会删除此新Node ,并且该Node不会被其他应用程序访问。

There are a number of ways to avoid this. 有很多方法可以避免这种情况。 The simplest would be to check if node is NULL before creating a new instance. 最简单的方法是创建新实例之前检查node是否为NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM