Copy a Tree without parent reference [duplicate] - java

This question already has answers here:
How to deep copy a Binary Tree?
(7 answers)
Closed 3 years ago.
I want to create a recursive method which can copy a tree and return it as a Tree not a Node. This is the structure:
public class Tree {
Node root;
public Tree(Node root)
this.root = root;
}
public static class Node {
int key;
Node left;
Node right;
public Node(int key, Node left, Node right) {
this.key = key;
this.left = left;
this.right = right;
}
}}

public Tree copy() {
if(root == null)
return new Tree(null);
else {
return new Tree(copyRec(root));
}
}
private Node copyRec(Node node) {
if(node != null) {
Node curr = new Node(node.key, null, null);
curr.left = copyRec(node.left);
curr.right = copyRec(node.right);
return curr;
}
return null;
}

Related

Mirror a binary tree

I have a simple Node class to construct a tree node in my binary tree:
class Node {
int data;
Node left;
Node right;
public Node(int i) {
this.data = i;
}
}
I've written a simple Tree class which will use the Node structure to build a tree:
class Tree {
Node root;
}
I'm trying to write a recursive function mirror() in my Tree class that will return a mirrored version of the tree (left and right nodes swapped).
So if I call this function on a Tree t, I would expect to start from the root, and swap all of the nodes until we reach a node that has no more children to swap. The part I'm struggling with is after we've swapped the root nodes children, how I can recursively call the mirror function on these nodes and then return the mirrored tree.
As you can see, the code below will swap the root node's children, but after that I am stuck as I can't call the mirror function on nodes, only a tree.
public Tree mirror() {
Node temp = this.root.left;
this.root.left = this.root.right;
this.root.right = temp;
If you could point me in the right direction I'd appreciate it.
You need a separate method that will accept Node object, mirror its children and call itself recursively.
public Tree mirror() {
mirrorInternal(this.root);
return this;
}
private void mirrorInternal(Node node) {
Node tmp = node.left;
node.left = node.right;
node.right = tmp;
if (node.left != null) {
mirrorInternal(node.left);
}
if (node.right != null) {
mirrorInternal(node.right);
}
}
I guess you could also change your Node-class such that it uses a flag for mirrored behavior:
class Node {
int data;
Node[] children;
public Node(int i) {
this.data = i;
this.children = new Node[2];
}
public void setLeft(Node node) {
children[0] = node;
}
public void setRight(Node node) {
children[1] = node;
}
public Node getLeft(boolean mirrored) {
return mirrored ? children[1] : children[0];
}
public Node getRight(boolean mirrored) {
return mirrored ? children[0] : children[1];
}
}
void mirror (Tree tree) {
mirror (tree.root);
}
Node mirror (Node node) {
if (node != null) {
Node temp = node.left;
node.left = mirror (node.right);
node.right = mirror (temp);
}
return node;
}

Is it possible to link multiple nodes to a single node?

I'm trying to make a tree structure based on the linked list. Since linked list can only directly point to the next node(For singly linked list), I would like to modify the concept of the linked list. Is it possible to point at the one node from multiple nodes?
Here is an image in drawing
I think the following would work:
class Node {
Node sibling;
Node child;
Object item;
}
sibling will point to next Node at parallel level, child points to Node on lower level.
See below my implementation:
package treeTest;
public class Node {
private Node left;
private Node right;
private String data;
public Node(String data) {
this.data = data;
left = null;
right = null;
}
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 String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package treeTest;
public class Tree {
private Node root;
public Tree() {
root = null;
}
public void insert(String data) {
root = insert(root, data);
}
private Node insert(Node node, String data) {
if(node == null) {
// Then create tree
node = new Node(data);
} else {
if(data.compareTo(node.getData()) <= 0) {
node.setLeft( insert(node.getLeft(), data));
} else {
node.setRight(insert(node.getRight(), data));
}
}
return node;
}
}
package treeTest;
import java.util.Scanner;
public class TestTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tree tree = new Tree();
tree.insert("Hurricane");
// Second level
tree.insert("Cat1");
tree.insert("Cat2");
tree.insert("Cat3");
}
}
For more details checkout this Java Program to Implement a Binary Search Tree using Linked Lists

Binary tree merge?

I am new to stack over flow so sorry for any mistakes, but i am trying to answer this question :
"Write a method that takes two binary trees t1, t2 and a binary tree node v as the arguments. It constructs and returns a new binary tree that has v as its root and whose left subtree is t1 and whose right subtree is t2."
I have done hours of attempts and cant seem to even make 1 binary tree.. The teacher wont really explain and wants us to do it using objects. This is the format she wants us to use.. Can someone please help me..
the commented out stuff is just my attempts to get something to work..
public class treeNode
{
private Object da;
private treeNode left;
private treeNode right;
public treeNode(Object newItem)
{
da = newItem;
left = null;
right = null;
}
public treeNode(Object newItem, treeNode leftNode, treeNode rightNode)
{
da = newItem;
left = leftNode;
right = rightNode;
}
public void setItem(Object newItem)
{
da = newItem;
}
public Object getItem()
{
return da;
}
public void setLeft(treeNode leftNode)
{
left = leftNode;
}
public treeNode getLeft()
{
return left;
}
public void setRight(treeNode rightNode)
{
right = rightNode;
}
public treeNode getRight()
{
return right;
}
//------------------------
public void buildTree()
{
}
//public void combine (l , r)
//{
// T = 5;
// setLeft(l);
// setRight(r);
// return T;
//}
//-----------------------
public static void main (String args [])
{
// treeNode a = new treeNode(5);
// treeNode b = new treeNode(8);
// treeNode c = new treeNode(2);
// a.setLeft(b);
// a.setRight(c);
// System.out.println(a.da);
// System.out.println(a.getLeft() );
// System.out.println(a.getRight() );
// treeNode t = new treeNode();
// t.left = t1;
// t.right = t2;
// System.out.println(buildTree(t));
}
}
My solution consists of two classes: Tree and Node.
The solution can be implemented with just Node, but since you were asked that the function will receive a two trees and a node so I implemented it like this. I don't know if you know java generics(The 'T' I used), if you don't, you can use Object like the code you posted. I'm ignoring all the getters and setters, but of course you can add them.
Node class:
public class Node<T> {
private T data;
private Node right;
private Node left;
public Node(T data) {
this.data = data;
}
public Node(T data, Node right, Node left) {
this.data = data;
this.right = right;
this.left = left;
}
}
Tree class:
public class Tree<T> {
private Node<T> root;
public Tree(Node root) {
this.root = root;
}
public Node<T> getRoot() {
return root;
}
}
The combine function:
public Tree combine(Tree t1, Tree t2, Node v) {
return new Tree(new Node(v, t1.getRoot(), t2.getRoot()));
}

error in creating a balanced binary tree using Java

I wrote this code to create a binary tree but looks like this code is creating an unbalanced binary tree. The nodes are getting only on the right subtree of root. I get Null pointer exception if I try to access child nodes of left subtree. I want to create a balanced binary tree with nodes getting inserted from left to right. What mistake am I doing here and how to rectify it?
public class binTree {
public static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
this.left = null;
this.right = null;
}
}
public TreeNode root;
public binTree(){
this.root = null;
}
public void insert(int data){
root = insert(root,data);
}
public TreeNode insert(TreeNode node,int data){
if(node == null){
node = new TreeNode(data);
//root = node;
}
else{
if(node.left == null){
node.left = insert(node.left,data);
}
else{
node.right = insert(node.right,data);
}
}
return node;
}
public static void main(String args[]){
binTree obj = new binTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.left.right.val); // this throws null pointer exception
}
}
You'll need to store the quantity of elements for every sub-tree at each tree-node like this:
public class BinTree {
private TreeNode root;
public static class TreeNode {
public int val;
public int elements = 0;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
public BinTree() {
this.root = null;
}
public void insert(int data) {
root = insert(root, data);
}
private static int height(TreeNode node) {
int result = 0;
if (node != null) {
result++;
int total = node.elements;
int heightElements = 2;
while (total > heightElements) {
total -= heightElements;
heightElements *= 2;
result++;
}
}
return result;
}
public TreeNode insert(TreeNode node, int data) {
if (node == null) {
node = new TreeNode(data);
} else if (height(node.left) == height(node.right)) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
node.elements++;
return node;
}
public static void main(String args[]) {
BinTree obj = new BinTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.val);
System.out.println(obj.root.left.val);
System.out.println(obj.root.right.val);
System.out.println(obj.root.left.left.val);
System.out.println(obj.root.left.right.val);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.right.right.val);
}
}

Why is the recursive insertion method of the BST not working

I wrote the following code to implement the recursive insert method for the BST. But when I print the tree in walk over order it prints the original tree before insertion. It seems as if the element was not inserted. Please help me out. Thanks in advance. Also please suggest the change in code. By the way, the intial tree in walk over order is 2 5 5 6 7 8.
package DataStructures;
class TreeNode {
private TreeNode parent;
private TreeNode childLeft;
private TreeNode childRight;
private int key;
public TreeNode(){
}
public TreeNode(int key) {
this(key, null);
}
public TreeNode(int key, TreeNode parent) {
this(key, parent, null, null);
}
public TreeNode(int key, TreeNode parent, TreeNode childLeft, TreeNode childRight) {
this.key = key;
this.parent = parent;
this.childLeft = childLeft;
this.childRight = childRight;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getChildLeft() {
return childLeft;
}
public void setChildLeft(TreeNode childLeft) {
this.childLeft = childLeft;
}
public TreeNode getChildRight() {
return childRight;
}
public void setChildRight(TreeNode childRight) {
this.childRight = childRight;
}
}
public class BinarySearchTreeBasicTest {
private static class BinarySearchTree {
private TreeNode root;
private TreeNode maxNode = new TreeNode(0);
public BinarySearchTree(TreeNode root) {
this.root = root;
}
public void printTheTreeInOrderWalk(TreeNode x) {
if (x != null) {
printTheTreeInOrderWalk(x.getChildLeft());
System.out.print(x.getKey() + " ");
printTheTreeInOrderWalk(x.getChildRight());
}
}
public void insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
insertNode(node.getChildLeft(), key);
} else if (node.getKey() < key){
System.out.println("k");
insertNode(node.getChildRight(), key);
} else{
// dont do anything
}
}
}
}
public static void main(String[] args) {
TreeNode rootNode = new TreeNode(6);
BinarySearchTree tree = new BinarySearchTree(rootNode);
TreeNode node1 = new TreeNode(5);
TreeNode node2 = new TreeNode(7);
rootNode.setChildLeft(node1);
rootNode.setChildRight(node2);
node1.setParent(rootNode);
node2.setParent(rootNode);
TreeNode node3 = new TreeNode(2);
TreeNode node4 = new TreeNode(5);
node1.setChildLeft(node3);
node1.setChildRight(node4);
node3.setParent(node1);
node4.setParent(node1);
TreeNode node5 = new TreeNode(8);
node5.setParent(node2);
node2.setChildRight(node5);
tree.insertNode(rootNode, 3);
tree.printTheTreeInOrderWalk(rootNode);
}
}
In your insertNode() method, you are just creating a new node; you are never adding the newly created node to its parent. You should check whether you are going to insert here or not or you should return the newly returned node and set it accordingly.
If you don't want too much deviation from your current program, you can make the following changes.
public void insertNode(TreeNode node, int key) {
if (node.getKey() > key) {
if (node.left == null) { //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.left = newNode;
} else {
insertNode(node.getChildLeft(), key);
}
} else if (node.getKey() < key) {
if(node.right == null){ //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.right = newNode;
} else {
insertNode(node.getChildRight(), key);
}
} else {
// don't do anything
}
}
In Java, parameters are passed by value. In insertNode, if you don't do anything else with the node, the line node = new TreeNode(key); will not do anything useful.
The typical implementation of an insertion in a tree works by returning the TreeNode that will replace the previous one:
private TreeNode insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
node.setChildLeft(insertNode(node.getChildLeft(), key));
} else if (node.getKey() < key){
node.setChildRight(insertNode(node.getChildRight(), key));
} else{
// dont do anything
}
}
return node;
}
Going a bit further, the previous method should actually be private. The public method should look like this:
public void insertNode(int key){
root = insertNode(root, key);
}

Categories

Resources