简体   繁体   English

如何为二叉树实现递归插入 function?

[英]How can I implement a recursive insert function for a binary tree?

I want to emphasize that I am specifically dealing with a binary tree, not a binary search tree (BST).我想强调的是,我专门处理二叉树,而不是二叉搜索树 (BST)。 The only requirements I have for this tree is that it should be balanced and insert children from left to right.我对这棵树的唯一要求是它应该是平衡的并且从左到右插入孩子。 I do not care about it being ordered or having duplicates.我不在乎它被订购或重复。

I ask this because most of the time I find examples of inserts for a binary tree, it is for a BST instead where there are no duplicates and we order things in a way that values less than the root node are stored at root.left and values that are higher than the root node get stored and root.right.我问这个是因为大多数时候我发现二叉树的插入示例,它是用于 BST 而不是没有重复的地方,我们以小于根节点的值存储在 root.left 和高于根节点的值被存储和 root.right。 I know how to implement that already, but would like to learn how to implement a basic insert for a regular binary tree.我已经知道如何实现它,但想学习如何为常规二叉树实现基本插入。 It is the recursive aspect that I am having difficulties with.这是我遇到困难的递归方面。

Also, I know it would be easier to do this using a data structure like a queue or a list but I would first like to attempt it without one.另外,我知道使用诸如队列或列表之类的数据结构来执行此操作会更容易,但我首先想在没有数据结构的情况下进行尝试。

Here is my insert function:这是我的插页 function:

    TreeNode insert(int data, TreeNode root, boolean isLeft){

    if(root == null){
        root = new TreeNode(data);
    }
    else if(root.left == null){
        root.left = new TreeNode(data);
    }
    else if(root.right == null){
        root.right = new TreeNode(data);

    }
    else{
        if(isLeft){
            insert(data, root.right, false);
        }
        else{
            insert(data, root.left, true);
        }
    }
    return root;
}

And here is what I am using to initialize the tree:这是我用来初始化树的内容:

public static void main(String[] args){

    TreeNode root = new TreeNode(1);

    boolean isLeft = false;

    for(int i = 2; i < 11; i++){
        isLeft = !isLeft;
       root = root.insert(i, root, isLeft);
    }

This produces a tree that looks like this:这会产生一棵看起来像这样的树:

│       ┌── 7
│   ┌── 3
│   │   └── 5
│   │       └── 9
└── 1
    │       ┌── 10
    │   ┌── 6
    │   │   └── 8
    └── 2
        └── 4

Which does not insert systematically from left to right.没有系统地从左到右插入。 Ideally it would look like this:理想情况下它看起来像这样:

│       ┌── 7
│   ┌── 3
│   │   └── 6
│   │        
└── 1
    │       
    │   ┌── 5
    │   │   └── 10
    └── 2   ┌── 9
        └── 4
            └── 8

The only reason it is numbered here is because I am using a for loop to create values but I do not care about number order, just left-to-right balance.它在这里编号的唯一原因是因为我正在使用 for 循环来创建值,但我不关心数字顺序,只关心从左到右的平衡。

If you would maintain the size of the tree then the binary representation of that size (plus 1) reveals which path to take to the next insertion point.如果您要保持树的大小,那么该大小的二进制表示(加 1)会显示通往下一个插入点的路径。

For instance, if the current tree is:例如,如果当前树是:

      1
    /   \
   2     3
  /
 4

then its size+1 is 5, which in binary is 101. Ignore the most significant bit -- which is always 1 -- and then interpret a 0 as left, and 1 as right.那么它的 size+1 是 5,在二进制中是 101。忽略最高有效位——它总是 1——然后将 0 解释为左边,将 1 解释为右边。 And indeed that is the path for reaching the spot where the next value must be injected:事实上,这是到达必须注入下一个值的位置的路径:

          1
(left)  /   \
       2     3
      / \ (right)
     4   5

Not the question, but it is overkill to have a root parameter, when the function is a method on a TreeNode instance, so you already have the root (ie this ).不是问题,但是当 function 是TreeNode实例上的方法时,拥有root参数是过大的,因此您已经拥有root (即this )。

Here is an implementation -- not recursive, as it is quite straightforward to do iteratively:这是一个实现——不是递归的,因为迭代执行起来非常简单:

    TreeNode insert(int data, int size) {
        TreeNode root = this;
        String bits = Integer.toBinaryString((size + 1) >> 1).substring(1);
        for (char bit : bits.toCharArray()) {
            root = bit == '1' ? root.right : root.left;
        }
        if (root.left == null) {
            root.left = new TreeNode(data);
        } else {
            root.right = new TreeNode(data);
        }
        return this;
    }

Call as:调用为:

        TreeNode root = new TreeNode(1);
        int size = 1;
        for(int i = 2; i < 11; i++){
            root.insert(i, size++);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM