【问题标题】:Binary Tree Insert Algorithm二叉树插入算法
【发布时间】:2013-05-19 02:14:44
【问题描述】:

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

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

通常在 BST 中,您只需检查 data

谁能帮我实现一个函数,只在二叉树中添加一个新节点,从左到右没有特定的顺序?

这是我的 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);
    }
  }
}

【问题讨论】:

  • 二叉搜索树是一种二叉树,其中节点中的数据以特定方式排序。因此,如果您已经实施了 BST,那么您几乎没有什么可做的......
  • 对。这就是我被困住的地方,我没有看到简单的方法......
  • 我应该只更改 检查它们是否为 Null 吗?
  • 我的回答对您解决问题有帮助吗?你还有什么想让我详细说明的吗?

标签: c++ tree insert binary-tree binary-search-tree


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    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    
    

    伪经典模式实现

      var BinaryTree = function(value){
        this.root = value;
        this.left = null;
        this.right = null;
      }
    
      BinaryTree.prototype.insert = function(value){
        //same logic as before
      }
    

    【讨论】:

      【解决方案3】:

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

      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 的根节点。

      【讨论】:

        【解决方案4】:

        我拿了 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(&amp;root, val);

        作为 root 指向节点结构的指针和 val 你要插入的整数值。

        希望对某人有所帮助。

        【讨论】:

        • 我对 C++ 的了解不够,无法自己做,所以您介意添加英文翻译(如果可能的话)吗?
        【解决方案5】:

        如果您知道这意味着什么,您应该尝试使用递归方法,例如 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 的教程,here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-13
          • 2019-08-26
          • 1970-01-01
          • 2020-08-22
          • 1970-01-01
          • 2022-01-14
          • 2016-01-17
          相关资源
          最近更新 更多