C++ 二叉树插入算法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16630823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:30:30  来源:igfitidea点击:

Binary Tree Insert Algorithm

c++treeinsertbinary-treebinary-search-tree

提问by Taylor

I recently finished implementing a Binary search tree for a project I was working on. It went well and I learned a lot. However, now I need to implement a regular Binary Tree... which for some reason has me stumped.

我最近为我正在从事的项目完成了二叉搜索树的实现。一切顺利,我学到了很多。但是,现在我需要实现一个常规的二叉树……出于某种原因,这让我很难过。

I'm looking for a way to do my InsertNode function..

我正在寻找一种方法来执行我的 InsertNode 功能..

normally in a BST you just check if data < root then insert left and vice versa. However, In a normal Binary tree, it is just filled from left to right, one level at a time..

通常在 BST 中,您只需检查 data < root 然后向左插入,反之亦然。然而,在普通的二叉树中,它只是从左到右填充,一次一层。

could anyone help me implement a function that just adds a new Node to the Binary tree from left to right in no specific order?

任何人都可以帮助我实现一个功能,该功能只是在没有特定顺序的情况下从左到右向二叉树添加一个新节点?

Here's my Insert for a BST:

这是我对 BST 的插入:

void Insert(Node *& root, int data)
{
  if(root == nullptr)
  {
    Node * NN = new Node;
    root = NN;
  }
  else
  {
    if(data < root->data)
    { 
      Insert(root->left, data);
    }
    else
    {
      Insert(root->right, data);
    }
  }
}

回答by bknopper

I am aware of the fact that this is a question posted some time ago, but I still wanted to share my thoughts on it.

我知道这是一个前一段时间发布的问题,但我仍然想分享我的想法。

What I would do (since this indeed is not very well documented) is use a Breadth-First-Search (using a queue) and insert the child into the first null I encounter. This will ensure that your tree will fill up the levels first before it goes to another level. With the right number of nodes, it will always be complete.

我会做的(因为这确实没有很好的记录)是使用广度优先搜索(使用队列)并将子项插入我遇到的第一个空值。这将确保您的树在进入另一个级别之前先填满这些级别。使用正确数量的节点,它将始终是完整的。

I haven't worked that much with c++, so to be sure it was correct I did it in Java, but you get the idea:

我没有用 C++ 做过那么多工作,所以为了确保它是正确的,我是用 Java 做的,但你明白了:

public void insert(Node node) {
    if(root == null) {
        root = node;
        return;
    }

    /* insert using Breadth-first-search (queue to the rescue!) */
    Queue<Node> queue = new LinkedList<Node>();
    queue.offer(root);

    while(true) {
        Node n = queue.remove();
        if(!n.visited) System.out.println(n.data);
        n.visited = true;

        if(n.left == null) {
            n.left = node;
            break;
        } else {
            queue.offer(n.left);
        }           

        if(n.right == null) {
            n.right = node;
            break;
        } else {
            queue.offer(n.right);
        }
    }
}

回答by cacoder

Javascript implementation (copy-paste ready for your web console):

Javascript 实现(为您的 Web 控制台准备好复制粘贴):

ES6 implementation (newer javscript syntax with class keyword)

ES6 实现(带有 class 关键字的较新的 javscript 语法)

  class BinaryTree {
      constructor(value){
          this.root = value;
          this.left = null;
          this.right = null;
      }

      insert(value){
          var queue = [];
          queue.push(this); //push the root
          while(true){
              var node = queue.pop();
              if(node.left === null){
                  node.left = new BinaryTree(value);
                  return;
              } else {
                  queue.unshift(node.left)
              }

              if(node.right === null){
                node.right = new BinaryTree(value);
                return;
              } else {
                queue.unshift(node.right)
              }
          }
      }
  }

  var myBinaryTree = new BinaryTree(5);
  myBinaryTree.insert(4);
  myBinaryTree.insert(3);
  myBinaryTree.insert(2);
  myBinaryTree.insert(1);

     5
   /   \
  4     3
 / \   (next insertions here)
 2  1    

Pseudoclassical pattern implementation

伪经典模式实现

  var BinaryTree = function(value){
    this.root = value;
    this.left = null;
    this.right = null;
  }

  BinaryTree.prototype.insert = function(value){
    //same logic as before
  }

回答by 0aps

I took bknopper code, modified a little bit and translated to C++. As he stated, surprisingly, this is not well documented.

我拿了 bknopper 代码,稍作修改并翻译成 C++。正如他所说,令人惊讶的是,这并没有得到很好的记录。

Here is the node structure and the insert function:

这是节点结构和插入函数:

struct nodo
{
    nodo(): izd(NULL), der(NULL) {};
    int val;
    struct nodo* izd;
    struct nodo* der;
};

void inserta(struct nodo** raiz, int num)
{

if( !(*raiz) )
{
    *raiz = new struct nodo;
    (*raiz)->val = num;
}
else
{

    std::deque<struct nodo*>  cola;
    cola.push_back(  *raiz  );

    while(true)
    {
        struct nodo *n = cola.front();
        cola.pop_front();

        if( !n->izd ) {
            n->izd = new struct nodo;
            n->izd->val = num;
            break;
        } else {
            cola.push_back(n->izd);
        }

        if( !n->der ) {
            n->der = new struct nodo;
            n->der->val = num;
            break;
        } else {
            cola.push_back(n->der);
        }
    }
  }
}

You call it this way: inserta(&root, val);

你这样称呼它: inserta(&root, val);

Being root a pointer to node struct and val the integer value you want to insert.

作为 root 指向节点结构的指针,并验证要插入的整数值。

Hope it helps someone.

希望它可以帮助某人。

回答by Pratik Nagelia

With a few modifications to your code, I hope this should help :

对您的代码进行一些修改,我希望这会有所帮助:

Node * Insert(Node * root, int data)
{
  if(root == nullptr)
  {
    Node * NN = new Node();
    root = NN;
    root->data = data;
    root->left = root ->right = NULL;

  }
  else
  {
    if(data < root->data)
    { 
      root->left = Insert(root->left, data);
    }
    else
    {
      root->right = Insert(root->right, data);
    }
  }
  return root;
}

Hence , this function returns the root node of the updated BST.

因此,该函数返回更新后的 BST 的根节点。

回答by devjeetroy

You should try using a recursive approach such as x = new (x), if you know what that means. This way, you don't really have to worry about the root node. I am going to write some pseudocode for you:

如果您知道这意味着什么,您应该尝试使用递归方法,例如 x = new (x)。这样,您就不必担心根节点。我将为您编写一些伪代码:

//public function
add(data){
    root = add(data, root)
}

//private helper function 
Node add(data, currentNode){
    if(currentNode = 0)
        return new Node(data)

    if(data less than currentNode's data)
        currentNode.left = add(data, currentNode.left)
    if(data more than currentNode's data)
        currentNode.right = add(data, currentNode.right)

    return currentNode      
}

I made a tutorial regarding the implementation of a BST in C++, here

我做了一个关于在 C++ 中实现 BST 的教程,这里