首页 文章

二叉树插入算法

提问于
浏览
9

我最近完成了为我正在进行的项目实现二进制搜索树 . 它进展顺利,我学到了很多东西 . 但是,现在我需要实现一个常规的二进制树...由于某种原因我难以理解 .

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

通常在BST中,您只需检查数据<root然后向左插入,反之亦然 . 但是,在普通的二进制树中,它只是从左到右填充,一次一个级别 .

任何人都可以帮我实现一个函数,只是从左到右添加一个新的节点没有特定的顺序?

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

5 回答

  • 13

    我拿了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);

    作为指向节点结构的指针,并指定要插入的整数值 .

    希望它可以帮到某人 .

  • 1

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

    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
      }
    
  • 4

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

  • 1

    对代码进行一些修改后,我希望这有助于:

    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

    我知道这是前一段时间发布的一个问题,但我仍想分享我对它的看法 .

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

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

相关问题