C ++-无法理解二叉树递归函数(插入)

时间:2020-02-24 13:47:40

标签: c++ tree insert binary-tree recursive-backtracking

我有一棵像这样的二叉树

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

我有这个“插入”功能,用于插入新节点并构建树

void insert(Node*& p, int key, double to_be_inserted) 
{
  if (p == nullptr) 
  {
    p = new Node;
    p->key = key;
    p->data = to_be_inserted;
    p->left = nullptr;
    p->right = nullptr;
  }
  else 
  {
    if (p->key == key) 
    {
      p->data = to_be_inserted;
    }
    else 
    {
      Node*& newChild = (p->key > key) ? p->left : p->right;
      insert(newChild, key, to_be_inserted);
    }
  }
}

和一个看起来像这样的主要功能

int main(int argc, char ** argv) 
{
  Node* root = nullptr;
  insert(root, 11, 11);
  insert(root, 6, 6);
  insert(root, 4, 4);
  insert(root, 5, 5);
  insert(root, 8, 8);
  insert(root, 10, 10);
  insert(root, 19, 19);
  insert(root, 17, 17);
  insert(root, 43, 43);
  insert(root, 31, 31);
  insert(root, 49, 49);

  printTree(root, 0);
  return 0;
}

最终的“打印输出”树看起来像这样

enter image description here

(此“打印输出”应从左到右而不是从上到下读取)

我不明白的是... insert函数何时决定回溯(备份树)并构建正确的子树?

例如,如果我们查看insert(root, 5, 5)中的insert(root, 8, 8)main,为什么8最终成为node 6的子节点而不是node 5。根据{{​​1}}函数的逻辑,它应该一直沿着树往下移动,并使insert成为8的子节点...对吗?

我需要帮助来正确理解插入功能。我确信我在逻辑上误解了一些。

谢谢(对冗长的帖子表示抱歉)!

1 个答案:

答案 0 :(得分:1)

当您插入8时,三个看起来像这样(X表示NULL):

insert(root, 11, 11);
insert(root, 6, 6);
insert(root, 4, 4);
insert(root, 5, 5);

        11
    6         X
 4    X    X     X
   5       

现在,当您尝试插入8(在此行Node*& newChild = (p->key > key) ? p->left : p->right;时,您首先要检查11 > 8是否正确,因此此行告诉您现在尝试插入8位于11子级,恰好扎根于6

这时,插入函数会重复自身,但是这三个函数的根不是11而是68大于6,因此它位于6的右侧。

这就是在插入8之前和之后的情况。


        11                             11                
    6         X                    6         X           
 4    X    X     X   =====>     4    8    X     X        
   5                             5                     

顺便说一句, 此功能存在回溯。这是一个简单的递归函数。