【问题标题】:Understanding pointers in binary tree理解二叉树中的指针
【发布时间】:2016-01-09 23:19:49
【问题描述】:

我是 C++ 新手,我通常使用 Java,所以我很难进入指针和引用。我必须使用内部节点和叶节点(只有叶包含数据)来做一个二叉搜索树的变体。

class Node
    Node *parent;
    Node *left;
    Node *right;
    //other stuff
}

我需要实现operator<<,它将一个具有值的新节点添加到树中。

//adding a node to tree
void operator<<(int value){
    if(size == 0){
        //stuff
    } else {
        Node* temp = root;
        getLeaf(temp,value);  
        //other magic        
        //temp will be used to append a new node into tree, 
        //so it has to point to the actual node in the tree
        delete temp;
    }        
}

getLeaf 函数的要点是找到一个叶子(可能包含也可能不包含所需的value)并将其存储到temp,它需要在operator&lt;&lt; 函数中访问。

int getLeaf( Node* temp, int value) const{
    int depth = 0;
    //goes trough all inner nodes until it finds specific leaf
    while(temp->isInner()){
        ++depth;
        if(value < temp->getValue()){ //searched value is smaller
            temp = temp->getLeft(); // to left subtree
            continue;
        } else {
            temp = temp->getRight(); //to rightsubtree
            continue;
        }
     return depth;
}

我真的很困惑如何做到这一点以及指针和值的正确组合是什么。如果我设置

    Node* temp = root;
    getLeaf(temp,value);  

getLeaf 函数中遍历树时,root 不会被覆盖吗?

另外我需要temp 指向树中的实际节点,所以我可以在其中添加一个新节点。

你能解释一下吗?

【问题讨论】:

  • 投反对票的原因是什么?
  • 这个问题非常针对您的问题,因此很难以对其他人有用的方式回答...但我认为您的 getLeaf 应该引用指针(Node*&amp; ,这样temp的实际值就可以在原来的调用者代码中更新了。
  • (我没有投反对票,但我明白为什么有人会投反对票 - 你的代码还不够完整,无法测试我们是否可以让它工作)
  • 谢谢,我会试试 Node*&。我的代码还没有完成,所以我还不能在这里发布 :) 但是 Node* temp = root; 呢? getLeaf 中给 temp 新分配的值不会影响整棵树吗?
  • 你说你懂Java。你可以看到,Java 对所有不是基本类型的东西都使用指针,比如intdouble。如果你在 Java 中有 void doSomething(MyClass object) 方法,你可以在 C++ 中编写 void doSomething(MyClass *object) 并使用 -&gt; 而不是 .。如果在 C++ 中编写void doSomething(MyClass object),则不能修改函数内部的参数,就像在 Java 中使用基本类型一样。引用是某种类型的语法糖。 Thay 像指针一样工作,但您不能更改目标,也不能取消引用它来访问值。

标签: c++ pointers


【解决方案1】:

从 Java 迁移到 C++ 有点困难。从 C++ 迁移到 Java 同样困难。为了让事情变得简单,您只需要进行试验。

在 C++ 中,指针是指向另一个变量在内存中的位置的变量,而引用是在语法上表现得像其地址所指向的变量的指针。

当参数被传递给函数时,函数确实接收原始参数而是它们的副本。您所做的工作是根据上述概念实现遍历。那么这一切“神奇地”是如何运​​作的呢?

您的函数:getLeaf(Node *&amp;temp, int value) 搜索正确的叶节点并将其分配给要执行插入的temptemp 这里是对指针 temp(在 operator &lt;&lt; 中)的引用的副本。所以当getLeaf中的引用temp被赋值时,它指向的operator &lt;&lt;中的指针temp就被修改了。

如果我设置

Node *temp = root;
getLeaf(temp,value);
在 getLeaf 函数中遍历树时不会覆盖 root 吗?

请注意这里temproot 是指向同一个变量的两个不同的指针。指针的内容是相同的,它们不是,因此当 temp 更新时,root 被覆盖。

但是后面的代码有问题。如果你delete temp;root 也将在插入结束时被删除,因为delete 删除了指针指向的内容。 NOT delete 不是由 new 分配的指针。

提供一个单独的函数来释放树使用的动态分配的内存,并在您完成实验时在最后调用它。

【讨论】:

  • 我实际上并不确定delete temp; 谢谢你的解释,它帮助了很多。
  • @Filoména Petržlénová 发布的 getLeaf 函数缺少右大括号,可能是 while 循环。
猜你喜欢
  • 1970-01-01
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2015-07-18
  • 2020-03-18
  • 1970-01-01
相关资源
最近更新 更多