Java 如何在不比较节点值的情况下使用递归实现完整的二叉树?

Java 如何在不比较节点值的情况下使用递归实现完整的二叉树?,java,data-structures,binary-tree,Java,Data Structures,Binary Tree,这是我实现的代码,但它实际上插入了两个相同的节点以使其保持平衡。有人能帮我修复这个bug或者用另一种方式实现它吗 我只想使用递归实现一个完整二叉树的插入。比如说,插入一个具有序列a、B、C、D、E、F的节点。它就像根是a,它的左子是B,右子是C,B的子是D和E,C的左子是F 我的代码有错误,但实现了这个插入,使树成为二叉树。这就像A的子对象是B和C。但是B的子对象是D,E和C的子对象也是D和E,而不是F。所以希望你们能帮助我修复这个bug,或者用递归的另一种方式实现它 幸运的是。我在Stack

这是我实现的代码,但它实际上插入了两个相同的节点以使其保持平衡。有人能帮我修复这个bug或者用另一种方式实现它吗

我只想使用递归实现一个完整二叉树的插入。比如说,插入一个具有序列a、B、C、D、E、F的节点。它就像根是a,它的左子是B,右子是C,B的子是D和E,C的左子是F

我的代码有错误,但实现了这个插入,使树成为二叉树。这就像A的子对象是B和C。但是B的子对象是D,E和C的子对象也是D和E,而不是F。所以希望你们能帮助我修复这个bug,或者用递归的另一种方式实现它


幸运的是。我在Stack Overflow上看到过类似的帖子,但我想使用递归实现它,而不是使用额外的数据结构。

递归方法只是隐式实现了链接到的示例中的显式堆栈。下面的C#程序显示了它是如何完成的。我认为您可以很容易地转换为Java

请注意,
TreeInsert
方法假定
root
节点不为空

public void recurInsert(BinaryTree.Node root, BinaryTree.Node newNode, int height) {
    if (newNode == null) {
        System.out.println("InsertNode is empty, please create new one");
        return;
    }
    else{
        if (height == 1) {
            if (root == null)
                return;
            else if (root.leftChild == null) {
                root.leftChild = newNode;
                System.out.println("left" + newNode.data);
            }
            else {
                root.rightChild = newNode;
                System.out.println("right" + newNode.data);
            }
        }
        else{
            if (root.leftChild != null)
                recurInsert(root.leftChild, newNode, height-1);
            //else (root.rightChild != null)
            //    recurInsert(root.rightChild, newNode, height-1);
            if (root.rightChild != null)
                recurInsert(root.rightChild, newNode, height-1);
        }
    }
}
公共类树节点
{
公共树节点左;
公共树节点权;
公共价值观;
}
私人无效文件()
{
树节点根=新树节点{Value=0};
对于(变量i=1;i<10;++i)
{
TreeInsert(根,新树节点{Value=i},i);
}
前序(根,0);
}
私有void树插入(树节点根,树节点项,int节点)
{
int parent=(节点-1)/2;
如果(父项==0)
{
if(root.Left==null)
root.Left=项目;
其他的
root.Right=项目;
}
其他的
{
TreeNode子级=((父级%2)==1)?根。左:根。右;
树插入(子项、项、父项);
}
}
私有void预排序(树状根,整数级)
{
if(root==null)返回;
WriteLine(“{0}{1}”,新字符串('-',2*级),root.Value);
前序(根左,级别+1);
预订单(根目录右侧,级别+1);
}
感谢Jim的c#code和他的解决方案。如果有人想尝试java,下面是java版本

    public class TreeNode
    {
        public TreeNode Left;
        public TreeNode Right;
        public int Value;
    }

    private void DoStuff()
    {
        TreeNode Root = new TreeNode {Value = 0};
        for (var i = 1; i < 10; ++i)
        {
            TreeInsert(Root, new TreeNode {Value = i}, i);
        }
        PreOrder(Root, 0);
    }

    private void TreeInsert(TreeNode root, TreeNode item, int node)
    {
        int parent = (node - 1)/2;
        if (parent == 0)
        {
            if (root.Left == null)
                root.Left = item;
            else
                root.Right = item;
        }
        else
        {
            TreeNode child = ((parent%2) == 1) ? root.Left : root.Right;
            TreeInsert(child, item, parent);
        }
    }

    private void PreOrder(TreeNode root, int level)
    {
        if (root == null) return;
        Console.WriteLine("{0}{1}", new String('-', 2*level), root.Value);
        PreOrder(root.Left, level+1);
        PreOrder(root.Right, level + 1);
    }
类BTnode
{
BTnode左;
BTnode-right;
int数据;
BTnode(int数据){
这个数据=数据;
}
/**实现它的最佳方法*/
void insert(BTnode root、BTnode newnode、int num){
if(root==null)返回;
否则{
int parent=(num-1)/2;
如果(父项==0){
if(root.left==null)
root.left=newnode;
其他的
root.right=newnode;
}
否则{
root=((父%2)==1)?root.left:root.right;//正确的路径
插入(根、新节点、父节点);
}
}
}
//使用bfs打印
无效bfs(BTnode根节点){
LinkedList ls=新建LinkedList();
LinkedList ls1=新建LinkedList();
链接列表t;
ls.addLast(根);
而(ls.size()!=0){
t=ls;
ls=ls1;
ls1=t;//交换两个列表以获得所有子级的一个级别
而(ls1.size()!=0){
BTnode temp=ls1.poll();
系统输出打印(温度数据+“”);
如果(左侧温度!=null)
ls.addLast(左侧温度);
如果(临时正确!=null)
ls.addLast(右侧温度);
}
System.out.println();
}
}
} 

我知道我迟到了,但是上面的答案有一些错误,使它们不完整的二叉树。找到正确的路径需要一直走到离根最近的祖先,而不仅仅是看父代。不过,我对函数做了很多修改,并在一个节点中包含了有关父节点的信息以进行说明

    class BTnode 
{
    BTnode left;
    BTnode right;
    int data;

    BTnode(int data) {
        this.data = data;
    }
    /**Best way to implement it*/
    void insert(BTnode root, BTnode newnode,int num){
        if (root == null) return;
        else{
            int parent = (num-1)/2;
            if( parent==0 ){
                if (root.left == null)
                    root.left = newnode;
                else 
                    root.right = newnode;
            }
            else {
                root = ((parent%2)==1) ? root.left:root.right; // correct path
                insert(root,newnode,parent);
            }
        }
    }
    //PRINT using bfs
    void bfs(BTnode root){
        LinkedList<BTnode> ls = new LinkedList<BTnode>();
        LinkedList<BTnode> ls1 = new LinkedList<BTnode>();
        LinkedList<BTnode> t;
        ls.addLast(root);
        while (ls.size() != 0) {
            t = ls;
            ls = ls1;
            ls1 = t;  // swap two list to get one level of all the children
            while(ls1.size()!=0) {
                BTnode temp = ls1.poll();
                System.out.print(temp.data+" ");
                if(temp.left != null) 
                    ls.addLast(temp.left);
                if(temp.right != null) 
                    ls.addLast(temp.right);
            }
            System.out.println();
        }
    }
} 
测试:

publicstaticvoidmain(字符串[]args)抛出java.lang.Exception
{
CompleteTree b=新的CompleteTree();
对于(int i=0;i
类树{
节点根=空;
int count=0,temp2=0;
公共void insertData(int i){
计数++;
temp2=计数;
根=创建节点(根,i);
}
/*
*在这个方法中,我试图在每个步骤中确定是选择左节点还是右节点来插入数据。
*/
私有节点createNode(节点root2,int i){
if(root2==null){
root2=新节点(i);
}否则{
int k=0,temp=0;
对于(int j=0;j//节点---
公共类二元树节点{
私有T数据;
私有二进制树节点leftNode;
私有二进制树节点;
公共二进制树节点(T数据){
这个数据=数据;
this.leftNode=null;
this.rightNode=null;
}
公共T getData(){
返回数据;
}
公共无效设置数据(T数据){
这个数据=数据;
}
公共二进制树节点getLeftNode(){
返回leftNode;
}
公共void setLeftNode(二进制树节点leftNode){
this.leftNode=leftNode;
}
公共二进制树节点getRightNode(){
返回右节点;
}
public void setRightNode(二进制树节点rightNode){
this.rightNode=rightNode;
}
}
//二叉树---
公共类二叉树{
私有二进制树节点rootNode;
公共二进制树节点getRootNode(){
返回根节点;
}
public void setRootNode(二进制树节点rootNode){
this.rootNode=rootNode;
}
公共空白插入(T数据){
this.setRootNode(插入(this.getRootNode(),data));
}
私有二进制树节点插入(二进制树节点,T数据){
if(node==null){
节点=新的二进制树节点(数据);
}否则{
如果(
class CompleteTree {
    Node root;

public CompleteTree() {
    root = null;
    } 

void insertWrapper(int value) {
    if (root == null) root = new Node(value);
        else insert(root,new Node(value));
    }

void insert(Node root, Node newnode) {
    if (((newnode.value - 1) / 2) == root.value) {
       if (root.left == null) {
            newnode.parent = root;              
            root.left = newnode;
       }
       else {
            newnode.parent = root;
            root.right = newnode;
       }
    }
    else {
       //goal to get ancestor 1 level under root to base the decision which subtree to go next
       int ancestor = parent;
       while (((ancestor - 1) / 2) > root.value) {
           ancestor = (ancestor - 1) / 2;
       }
       root = ((ancestor%2)==1) ? root.left : root.right;
       insert(root,newnode);
    }
    }


void printInorder(Node root) {
    if (root == null) return;
    printInorder(root.left);
    System.out.print("Hi, i am "+root.value+" and my parent is ");
    if (root.parent == null) System.out.println ("NULL");
        else System.out.println(root.parent.value);
    printInorder(root.right);
    }
}

class Node {
    int value;
    Node left;
    Node right;
    Node parent;

public Node (int value) {
    this.value = value;
    left = null;
    right = null;
    parent = null;
    }

public Node (int value, Node parent) {
    this.value = value;
    left = null;
    right = null;
    this.parent = parent;
    }
}
public static void main (String[] args) throws java.lang.Exception
{
    CompleteTree b = new CompleteTree();
    for (int i=0; i<10; i++) {
        b.insertWrapper(i);
    }
    b.printInorder(b.root);
}
class Tree {
    Node root = null;
    int count = 0, temp2 = 0;

    public void insertData(int i) {
        count++;
        temp2 = count;

        root=createNode(root, i);

    }
/*
 * Here in this method I am trying to figure out at each step whether to select the left node or right node to insert the data.
 */
    private Node createNode(Node root2, int i) {

        if (root2 == null) {
            root2 = new Node(i);
        } else {

            int k = 0, temp = 0;
            for (int j = 0; j < temp2; j++) {
                temp = (int) (temp + Math.pow(2, j));
                k = j;
                if (temp2 - temp <= 0) {
                    temp = (int) (temp - Math.pow(2, j));
                    break;
                }

            }

            if (temp2 - temp <= Math.pow(2, k) / 2) {
                temp = 1;
                for (int j = 1; j < k; j++) {
                    temp = (int) (temp + Math.pow(2, j) / 2);
                }
                temp2 = temp2 - temp;
                root2.setLeft(createNode(root2.getLeft(), i));
            } else {
                temp = 1;
                for (int j = 1; j <= k; j++) {
                    temp = (int) (temp + Math.pow(2, j) / 2);
                }
                temp2 = temp2 - temp;

                root2.setRight(createNode(root2.getRight(), i));
            }

        }

        return root2;
    }

    public void printInorder()
    {
    printInorder(root);     
    }

    public void printInorder(Node node)
    {
        if (node == null)
            return;

        /* first recur on left child */
        printInorder(node.left);

        /* then print the data of node */
        System.out.print(node.data + " ");

        /* now recur on right child */
        printInorder(node.right);
    }

    private class Node {
        Node left;
        Node right;
        int data;

        Node(int i) {
            data = i;
        }

        public Node getLeft() {
            return left;
        }

        public void setLeft(Node left) {
            this.left = left;
        }

        public Node getRight() {
            return right;
        }

        public void setRight(Node right) {
            this.right = right;
        }

        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }
    }

}

public class BinaryTree {
    public static void main(String[] args) {

        Tree t = new Tree();
        t.insertData(1);
        t.insertData(2);
        t.insertData(3);
        t.insertData(4);
        t.insertData(5);
        t.insertData(6);
        t.insertData(7);
        t.insertData(8);
        t.insertData(9);
        t.insertData(10);
        t.insertData(11);
        t.insertData(12);
        t.insertData(13);
        t.insertData(14);

    t.printInorder();

    }
}
//Node---
public class BinaryTreeNode<T> {
    private T data;
    private BinaryTreeNode<T> leftNode;
    private BinaryTreeNode<T> rightNode;

public BinaryTreeNode(T data) {
    this.data = data;
    this.leftNode = null;
    this.rightNode = null;
}

public T getData() {
    return data;
}

public void setData(T data) {
    this.data = data;
}

public BinaryTreeNode<T> getLeftNode() {
    return leftNode;
}

public void setLeftNode(BinaryTreeNode<T> leftNode) {
    this.leftNode = leftNode;
}

public BinaryTreeNode<T> getRightNode() {
    return rightNode;
}

public void setRightNode(BinaryTreeNode<T> rightNode) {
    this.rightNode = rightNode;
}
}

//Binary Tree---
public class BinaryTree<T> {
private BinaryTreeNode<T> rootNode;

public BinaryTreeNode<T> getRootNode() {
    return rootNode;
}

public void setRootNode(BinaryTreeNode<T> rootNode) {
    this.rootNode = rootNode;
}

public void insert(T data){
    this.setRootNode(insert(this.getRootNode(), data));
}

private BinaryTreeNode insert(BinaryTreeNode<T> node, T data){
    if(node == null){
        node = new BinaryTreeNode<>(data);
    }else{
        if(node.getLeftNode() == null){
            node.setLeftNode(insert(node.getLeftNode(), data));
        }else if(node.getRightNode() == null){
            node.setRightNode(insert(node.getRightNode(), data));
        } else{
            if(node.getLeftNode().getLeftNode() == null || node.getLeftNode().getRightNode() == null){
                insert(node.getLeftNode(), data);
            }else if(node.getRightNode().getLeftNode() == null || node.getRightNode().getRightNode() == null){
                insert(node.getRightNode(), data);
            }else{
                insert(node.getLeftNode(), data);
            }
        }
    }
    return node;
}
}