【问题标题】:Binary Search Tree in C++C++ 中的二叉搜索树
【发布时间】:2012-11-08 20:09:37
【问题描述】:

我正在学习 C++ 语言,并且正在尝试编写 BST,但出现了问题。 我尝试将元素添加到空树,root 为 NULL,但在添加元素后,root 仍然为 NULL,尽管添加成功(我在调试模式下看到它,节点设置为 tmp)。我不知道为什么会这样。

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

【问题讨论】:

  • 我会说使用new 不会使这段代码成为C++ ...你在这里做的或多或少是香草C。

标签: c++ binary-search-tree


【解决方案1】:

当您将指针传递给函数时,您会创建指针的本地版本。这个局部变量 (node) 确实指向与您传递的外部指针相同的内存。然而,任何改变这个变量不是它指向的内存,而是指针变量本身)的尝试只会改变局部变量。

所以您的node 指向与您的tree 相同的内存位置,但node 变量本身不等于tree 变量,因此您的更改从外部函数不可见。

这听起来很复杂,抱歉,但这和这里完全一样:

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

当然在这种情况下var 不会改变,而是在函数内部改变a

要解决此问题,请传递对指针的引用而不是指针本身:

void addToNode(Node*& node, int value)

【讨论】:

    【解决方案2】:

    在函数addToNode 中,当您分配给node 时,该分配在调用addToNode 的函数中不可见,因为node 是一个局部变量。

    您应该将其作为参考传递:

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

    【讨论】:

      【解决方案3】:

      Joachim 已经在答案上击败了我,但无论如何我都会添加这个观察结果。

      您的代码泄漏内存。

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

      addToNode 的每次调用都会在tmp 中创建一个新的Node 实例,但是如果参数Node* node 不是NULL,则这个新的Node 不会被删除,并且不会被其他人访问应用程序。

      有很多方法可以避免这种情况。最简单的方法是在创建新实例之前检查node 是否为NULL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 2011-01-31
        • 1970-01-01
        • 1970-01-01
        • 2013-04-14
        • 1970-01-01
        相关资源
        最近更新 更多