【问题标题】:Binary Tree search returns no results (C++)二叉树搜索不返回任何结果 (C++)
【发布时间】:2011-09-01 05:26:21
【问题描述】:

我正在研究一些二叉树算法,需要一个“使用 searchindex... 查找节点”功能。树节点的设计基本上是

class TreeNode {
  int index; // some identifier
  TreeNode *left;
  TreeNode *right;
}

树是由指向根节点的指针定义的。

我对搜索功能的实现是:

void Tree::searchNode(TreeNode * root, int nodeIndex, TreeNode *resultNode){
/* Recursive search */

  if (root->index == nodeIndex) {
            resultNode = root;
  } else {

    /*  search children if the current node is not a leaf */

    if(!root->isLeaf()) {
        this->searchNode(root->left,nodeIndex,resultNode);
        this->searchNode(root->right,nodeIndex,resultNode);
        }
  }
}

参数: *root 是树的根节点,nodeIndex 是搜索索引,*resultNode 是指向树中找到(或未找到)节点的指针。

该函数不返回指向找到的节点的引用或指针,而是修改指针resultNode,使其指向找到的节点。这个想法是用 NULL 初始化 resultNode,执行搜索并在匹配发生时修改它。否则它仍然为 NULL,我可以很容易地检查是否有搜索结果。

另一个以树buildingTree为成员的类以这种方式利用搜索功能:

TreeNode *resultNodePtr = NULL;
this->buildingTree->searchNode(this->buildingTree->rootPtr, 
                               currentNodeIndex, resultNodePtr);

// do sth. with resultNodePtr if != NULL

我在堆栈上创建 *resultNodePtr 因为我只是在函数内部临时需要它。这是否正确完成?但是:该功能不起作用。 resultNodePtr 始终为 NULL,即使树包含具有搜索索引的节点。我一步步调试得很仔细,它检测到了

(root->index == nodeIndex)

正确但是

  resultNode = root; 

不起作用(我希望 resultNode 指向 root 指向的相同地址)。 调试器说 resultNode 在赋值之前是 0x0,root 节点是某个地址,在赋值之后 resultNode 仍然是 0x0。

在这种情况下,我是否必须为 TreeNode 类重载 operator=?

我试过了:

TreeNode & TreeNode::operator=(const TreeNode & oldTreeNode){
 *this = oldTreeNode;
 return *this;
 // ignore childs for now
}

我不是专家,但这个 operator= 似乎微不足道。对两个TreeNode指针*node1 = *node2的赋值有影响吗?

也许你可以帮助我。感谢阅读,感谢您的帮助。 如果我自己找到解决方案,我会在这里发布。

问候, 标记

【问题讨论】:

  • 是否有理由传入指针并进行修改?仅使用返回值似乎更干净,并且可以避免以下答案中解释的问题。
  • 与您的问题完全无关,但通常对树进行排序,并且可以以更快的方式实现搜索。您是否有理由搜索树的每个节点?实际上,您的班级在 std::list 上的搜索速度比 std::find 慢!
  • 另外,您实现的 operator= 是一个无限递归循环。它应该类似于index = oldTreeNode.index; left=(oldTreeNode.left?new TreeNode(*oldTreeNode.left):nullptr); right=(oldTreeNode.right?new TreeNode(*oldTreeNode.right):nullptr);
  • 并且任何具有拥有堆分配数据的指针的类都应遵守五规则:stackoverflow.com/questions/4782757/…
  • @mdw:是的,返回值更好,现在我知道我犯的错误我改回来了。

标签: c++ search binary-tree


【解决方案1】:

因为您将resultNode 作为值指针传递给函数,所以它的原始值永远不会改变。将TreeNode* 视为实际上只是一个表示内存地址的数字;当你重新分配它时:

resultNode = root;

这会修改searchNode 拥有的副本,但不会修改调用searchNode 的代码中的原始指针。举个更简单的例子:

void Foo(int x)
{
    x = 100;
}

void Bar()
{
    int x = 0;
    Foo(x);
    // at this point, x is still 0
}

resultNode 的值不会从 NULL 更改,原因与调用函数 Barx 不会从 0 更改的原因相同。要解决此问题,请将指针作为指向指针的指针或通过引用传递的指针:

void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode*& resultNode)
{
    // same code
}

... 或:

void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode** resultNodePtr)
{
    // assign to *resultNodePtr instead
}

【讨论】:

  • 问题已修复。非常感谢详细的帮助。 :)
【解决方案2】:

您的 resultNode 指针是按值传递的,而不是按引用传递的。所以当函数调用完成时,调用方的指针没有收到值。

你的算法看起来不错:)

【讨论】:

  • 问题已修复。谢谢你的帮助! :)
猜你喜欢
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 2023-03-08
相关资源
最近更新 更多