二叉树插入算法

11

我最近完成了一个二叉搜索树项目的实现,进展顺利并学到了很多。然而,我需要实现一个常规的二叉树......这让我感到困惑。

我正在寻找一种方法来执行我的InsertNode函数..

通常在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);
    }
  }
}

2
二叉搜索树是一种二叉树,其中节点数据按特定方式排序。因此,如果您已实现了BST,则需要做的工作很少... - Mitch Wheat
没错。不过,我现在遇到了困难,我看不出有简单的方法来实现这个... - Taylor
我应该只是将< >检查更改为检查它们是否为空吗? - Taylor
我的回答有帮助解决问题吗?还有其他需要我详细说明的地方吗? - bknopper
5个回答

13

我知道这是一篇发布很久以前的问题,但我仍然想分享我的想法。

如果我要做的话(因为这确实没有很好的文档),我会使用广度优先搜索(使用队列),并将子节点插入遇到的第一个空节点中。这样可以确保您的树先填满每个级别,然后再去另一个级别。通过正确数量的节点,它将永远是完整的。

我没有太多使用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);
        }
    }
}

5

Javascript 实现(可复制粘贴至您的网页控制台):

ES6 实现(使用“class”关键字的新一代 JavaScript 语法)

  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    

伪经典模式实现
  var BinaryTree = function(value){
    this.root = value;
    this.left = null;
    this.right = null;
  }

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

2

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

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;
}

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

1
我采用了bknopper的代码,做出了一些修改并将其翻译成了C ++。正如他所说,令人惊讶的是,这并没有得到很好的记录。
以下是节点结构和插入函数:
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);
        }
    }
  }
}

您需要这样调用它: inserta(&root, val); 其中root是指向节点结构的指针,val是要插入的整数值。
希望对某些人有所帮助。

我自己不太懂C++,你能否添加一个英文翻译(如果可能的话)? - Joshua Grosso Reinstate CMs

0

如果你知道什么是递归,那么你应该尝试使用递归方法,例如 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      
}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接