【问题标题】:C++: Pointer vs Pointer of Pointer to insert a node in a Binary TreeC ++:在二叉树中插入节点的指针与指针指针
【发布时间】:2015-07-18 19:12:01
【问题描述】:

我正在创建一个在二叉树中插入元素的函数,首先,我在 Visual Studio 2012 上执行了以下操作:

void Insert(Nodo *root, int x){
   if(root == NULL){
      Nodo *n = new Nodo();
      n->value = x
      root = n;
      return;
   }
   else{
      if(root->value > x)
         Insert(&(root)->left, x);
      else
         Insert(&(root)->right, x);
   }
}

但同样的代码在 Dev-C++ 中不起作用,我需要使用 Pointer of Pointer 才能使其工作,如下所示:

void Insert(Nodo **root, int x){
   if(*root == NULL){
      Nodo *n = new Nodo();
      n->value = x
      *root = n;
      return;
   }
   else{
      if((*root)->value > x)
         Insert(&(*root)->left, x);
      else
         Insert(&(*root)->right, x);
   }
}

有人知道为什么会这样吗?

【问题讨论】:

  • 但是为什么它在 Visual Studio 中工作?我可以插入和搜索所有元素
  • 如果是这样,它这样做只是因为您在调用者端使用非空地址启动了root(您的帖子中不方便地缺少该代码以及节点定义)到有效的Node。即使这样,如果leftrightNodo*,那么&(root)->left 应该是Nodo**,并且该调用甚至不应该编译。或许,当它神奇地编译时,您是否在 same 源文本中有 both 这两个实现,如果是这样,您是否考虑过第一个可能通过重载解析调用第二个关于那些递归?
  • 我为第一条评论中的int*int** 道歉,它们应该分别是Nodo*Nodo**。漫长的一天。无论如何,see broken code here.
  • 因为要修改的是指针本身;不仅仅是它指向的东西。尽管数组(当作为参数传递时表示为指向第一个元素的指针)和 C++ 引用,C/C++ 中的所有参数都是按值传递的。也就是说,传递Node* 传递地址in 的指针。这还不够好。您需要指针地址,以便可以修改指针本身。否则,它与传递 int x、调用 foo(n) 并期望 n 在调用方修改回没有什么不同。
  • 我试图解析那句话,但你的第一个代码只是改变了局部变量root 的值(它只是一个局部变量;也许那是您没有看到的断开连接),它最初只是保存您传入的任何内容的 。该更改不会影响值 来自的位置呼叫者,召集者。如果您想在 C-fashion 中按地址修改某些东西(就是这样),那么您需要传递 您要修改的东西的地址,将参数声明为指向类型的指针并取消引用要保存到的指针。

标签: c++ pointers visual-studio-2012 pass-by-reference dev-c++


【解决方案1】:

第一个代码不应该编译。事实上,它不能在 MSVC 2013 下编译。

为什么?

你的节点结构应该是这样的:

struct Nodo {
    int value; 
    Nodo*left, *right;  // pointer to the children nodes
};

这意味着(root)->leftNodo* 类型。因此&(root)->leftNodo** 类型,它与Nodo* 参数不兼容。

无论如何,在您的插入函数中,您肯定想要更改树。但是,例如,如果您这样做:root = n; 您只需更新根参数(指针)。一旦您离开该功能,此更新就会丢失。在这里,您当然想要更改根节点的内容,或者更可能更改指向根节点的指针。

在第二个版本中,您将指向节点的指针地址作为参数传递,然后在必要时更新此指针(预期行为)。

备注

第一个版本可以“保存”,如果你想通过引用传递:

void Insert(Nodo * &root, int x){  // root then refers to the original pointer 
   if(root == NULL){   // if the original poitner is null... 
      Nodo *n = new Nodo();
      n->value = x
      root = n;        // the orginal pointer would be changed via the reference    
      return;
   }
   else{
      if(root->value > x)
         Insert(root->left, x);   // argument is the pointer that could be updated
      else
         Insert(root->right, x);
   }
}

【讨论】:

  • 我不明白为什么如果我说“嘿指向左边 Nodo 的指针,指向这个新 Nodo 指向的同一个地方”,然后指向左边节点的指针就会丢失参考,但如果我使用指针告诉左指针做同样的事情,它可以工作
  • Ops,我想我明白了:我的函数将创建一个指向传递的指针的指针“root”,所以当我执行“root = n”时,只有在此创建的指针函数将指向“n”,而不是前一个 Nodo 的左指针。当我使用指向指针的指针时,我告诉左指针指向我想要的位置......对吗?
猜你喜欢
  • 2019-12-13
  • 2019-03-12
  • 2021-11-30
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多