Java 如何在不比较节点值的情况下使用递归实现完整的二叉树?
这是我实现的代码,但它实际上插入了两个相同的节点以使其保持平衡。有人能帮我修复这个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,或者用递归的另一种方式实现它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
幸运的是。我在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;
}
}