void access(T elem)
This function should determine whether the given element is in the tree. If so, the tree should semi-splay so that the node with the given element is moved towards the root of the tree when the function returns. If the given element is not found in the tree, it should simply be inserted into the tree (with no splaying).
Here is Node class
public class Node<T> {
public T elem = null;
public Node<T> left = null;
public Node<T> right = null;
public Node(T _elem) {
elem = _elem;
}
public String toString() {
String out = elem.toString();
out += " [L: "+ (left == null ? "null" : left.elem) + "] ";
out += " [R: "+ (right == null ? "null" : right.elem) + "] ";
return out;
}
}
Related
I created a double-linked list and it can run without any error.But it will occur java.lang.StackOverflowError at adding second element when i use debug to examine this program.If i don't override toString(),the program will be normal.But i want to know why don't override toString()?
package com.study.testcollection.com.study.testlinkedlist;
public class Node {
private Node per;
private Object obj;
private Node next;
public Node getPer() {
return per;
}
public Object getObj() {
return obj;
}
public Node getNext() {
return next;
}
public void setPer(Node per) {
this.per = per;
}
public void setObj(Object obj) {
this.obj = obj;
}
public void setNext(Node next) {
this.next = next;
}
#Override
//if don't write this function,the program will be normal.Why?
public String toString() {
return "Node{" +
"per=" + per +
", obj=" + obj +
", next=" + next +
'}';
}
}
package com.study.testcollection.com.study.testlinkedlist;
public class Mylinkedlist {
Node first = null;
Node last = null;
public void add(Object e){
if (first == null){
Node n = new Node();
n.setObj(e);
n.setPer(null);
n.setNext(null);
first = n;
last = n;
}
else{
Node n = new Node();
n.setObj(e);
last.setNext(n);
n.setPer(last);
n.setNext(null);
last = n;
}
}
public static void main(String[] args) {
Mylinkedlist a = new Mylinkedlist();
a.add("hello");
a.add("Bob");//occur error when it is executed
}
}
Your "next" field is pointing to a Node and thus Node.toString() is called infinitely resulting in stackoverflow.
If you need to use toString() method, you can modify it as follows :
public String toString() {
String n = next != null ? next.obj.toString():"null";
String p = per != null ? per.obj.toString():"null";
return "Node{" +
"per=" + p +
", obj=" + obj +
", next=" + n +
'}';
}
This is how it looks. When you do :
System.out.println(a.first.toString());
And when toString is defined as:
public String toString() {
return "Node{" +
"per=" + per +
", obj=" + obj +
", next=" + next +
'}';
}
You attempt in printing the next which is n
n attempts in printing the previous per
Previous per again attempts in printing next
next makes a call to previous per and so on...
Resulting in stackoverflow as the call never ends. You are again and again iterating in the forward arrow and previous arrow as shown in image above.
To fix it, you can remove toString from Node and replace with:
public String forward() {
return "Node{" +
", obj=" + obj +
", next=" + next +
'}';
}
public String backward() {
return "Node{" +
", obj=" + obj +
", prev=" + per +
'}';
}
I've been trying to switch over to Java from Node and one thing I'm wondering about is how to print an object such as a binary Tree in a similar format to how node would display it. For instance, my binary tree initiation code is as follows:
public class BinaryTree {
int data;
BinaryTree left, right;
public static void main(String[] args) {
BinaryTree tree = new BinaryTree(1);
tree= new BinaryTree(1);
tree.left = new BinaryTree(2);
tree.right= new BinaryTree(3);
tree.left.right = new BinaryTree(4);
System.out.println(tree); // output -> BinaryTree#4554617c
}
public BinaryTree(int data) {
super();
int val;
this.left = this.right = null;
}
}
In node, this binary tree would be displayed as the following:
TreeNode {
val: 1,
right: TreeNode { val: 3, right: null, left: null },
left:
TreeNode {
val: 2,
right: TreeNode { val: 4, right: null, left: null },
left: null } }
However in Java, when I do
System.out.println(tree);
the output -> BinaryTree#4554617c
What is the proper way to print my BinaryTree and what's a good way to do this? Is there a way to print the tree in a JSON format?
Printing tree will give you the memory address of the main tree node. If you want to print the content of the tree, you will need to implement a recursive print method and recurse over each node in the tree.
If the node is a final node (no right or left tree) print the content of that node. Otherwise move down the tree.
You can print on the way down the tree or on the way back depending on how you want the tree to look.
I hope I understood the question correctly.
I found this solution on stack overflow and modified it...
public static class TreeNode
{
int value;
TreeNode leftChildren;
TreeNode rightChildren;
public TreeNode(int value, TreeNode left, TreeNode right)
{
this.value = value;
this.leftChildren = left;
this.rightChildren = right;
}
public addLeftNode(TreeNode node)
{
this.leftChildren = node;
}
public addRightNode(TreeNode node)
{
this.rightChildren = node;
}
public void print(String prefix)
{
print(prefix, true);
}
private void print(String prefix, boolean isTail)
{
System.out.println(prefix + (isTail ? "└── " : "├── ") + this.toString());
if(null != leftChildren)
{
leftChildren.print(prefix + (isTail ? " " : "│ "), (null == rightChildren ? true : false));
}
if(null != rightChildren)
{
rightChildren.print(prefix + (isTail ?" " : "│ "), true);
}
}
#Override public String toString()
{
return "TreeNode { Value: " + this.value + "}";
}
}
The first node represents the left and the second node the right node in th binary tree.
EDIT: You can use this like this:
TreeNode root = new TreeNode(22, null, null);
root.addLeftNode(new TreeNode(15, null, null));
root.addRightNode(new TreeNode(35, new TreeNode(27, null, null), null));
root.print(); // This will print recursively all sub-nodes
Alternate you can write a wrapper class like this:
public class BinaryTree
{
private TreeNode root;
// implementation of getters and setters
public void print()
{
this.root.print();
}
}
This is the Java program I wrote to create a Binary Tree and insert elements into it. However, I could not write the program for inserting the elements recursively and thus had to manually specify the left and right children respectively.
Here is my code:
public class BinTree {
private Node root;
private class Node {
Node left;
Node right;
int data;
private Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public BinTree() {
root = null;
}
public void preorder(Node temp) {
temp = root;
if(temp != null) {
System.out.print(temp.data + " ");
preorder(temp.left);
preorder(temp.right);
}
}
public void add() {
root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.left = new Node(60);
}
public static void main(String[] args) {
BinTree bt = new BinTree();
bt.add();
System.out.print(bt.root.data);
System.out.print(" " + bt.root.left.data);
System.out.print(" " + bt.root.right.data);
System.out.print(" " + bt.root.left.left.data);
System.out.print(" " + bt.root.left.right.data);
}
}
Also, the preorder traversal I wrote for the above program failed and I got some unending output. Had to kill the execution!
Hence if some one could provide me the correct implementation of inserting elements into binary tree recursively it would be of great help.
Also, if possible, could you please tell me where i made a mistake in my preorder traversal?
Thanks in advance!
To answer the question in part, the preorder function contains a bug as it does not actually traverse the tree but starts from the root over and over again. Change it to
public void preorder(Node temp)
{
if(temp != null)
{
System.out.print(temp.data + " ");
preorder(temp.left);
preorder(temp.right);
}
}
and call it with the root of the tree as an argument.
I have a working program that prints each level of a (complete) binary tree, using the "preferred" method of an iterative function (see code below), but I would like to see how one would implement the same program, but using a recursive method.
Although I agree that normally having someone write code for me is not conducive to good learning; I have more trouble learning how to do something without having seen a working implementation beforehand (because no precedent has been set).
What I have so far (iterative program):
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Collections;
public class BinaryTreeLevelWise<T extends Comparable<T>> {
/*
* This class represents the individual nodes of the binary tree
* Each node has a left, right pointer of type Node
* and Value to hold the value
*/
class Node<T> {
Node left;
Node right;
T value;
public Node(T value) {
this.value = value;
}
#Override
public String toString() {
return "Node value=" + value + "";
}
}
public static void main(String[] args) {
new BinaryTreeLevelWise().run();
}
/*
* This function inserts an element into the binary tree
*/
public <T> void insert(Node node, T value) {
if (((Comparable<T>) value).compareTo((T) node.value) < 0) {
if (node.left != null) {
insert(node.left, value);
} else {
System.out.println(" Inserted " + value + " to left of "
+ node.value);
node.left = new Node(value);
}
} else if (((Comparable<T>) value).compareTo((T) node.value) > 0) {
if (node.right != null) {
insert(node.right, value);
} else {
System.out.println(" Inserted " + value + " to right of "
+ node.value);
node.right = new Node(value);
}
}
}
public void run() {
Node root = new Node(5);
System.out.println("Building tree with root value " + root.value);
insert(root, 1);
insert(root, 8);
insert(root,-2);
insert(root, 6);
insert(root, 3);
insert(root, 9);
insert(root,-3);
insert(root,-1);
insert(root,-4);
System.out.println("*************\nPrinting the tree level by level");
printLevelWise(root);
}
/*
* This functions uses a list of nodes and prints them level by level,
* assuming a complete binary tree.
*/
public void printLevelWise(Node root) {
List<List<Node>> levels = traverseLevels(root);
int i = 0;
for (List<Node> level : levels) {
System.out.print("Level " + i + ": ");
for (Node node : level) {
System.out.print("node " + node.value + " -> ");
}
System.out.println();
i++;
}
}
/*
* This function traverses the tree and puts all the nodes into a list, level by level
*/
private List<List<Node>> traverseLevels(Node root) {
if (root == null) {
return Collections.emptyList();
}
List<List<Node>> levels = new LinkedList<>();
Queue<Node> nodes = new LinkedList<>();
nodes.add(root);
while (!nodes.isEmpty()) {
List<Node> level = new ArrayList<>(nodes.size());
levels.add(level);
for (Node node : new ArrayList<>(nodes)) {
level.add(node);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
nodes.poll();
}
}
return levels;
}
}
This code outputs the following (which I believe to be the correct output):
Level 0: node 5 ->
Level 1: node 1 -> node 8 ->
Level 2: node -2 -> node 3 -> node 6 -> node 9 ->
Level 3: node -3 -> node -1 ->
Level 4: node -4 ->
Any ideas on how to make this program use a recursive method instead of an iterative method?
You can try below code for recursive way but if you compare complexity by then Queue way is better in compare to recursive method to traverse level order
public void printLevelOrder(Node<T> root)
{
int h = height(root);//Calculate height of the tree
int i;
for (i=1; i<=h; i++)
{
printGivenLevel(root, i);
System.out.println();
}
}
private void printGivenLevel(Node<T> root, int height) {
if (root == null)
return;
if (height == 1)
System.out.print(root.value);
else if (height > 1)
{
printGivenLevel(root.left, height-1);
printGivenLevel(root.right, height-1);
}
}
As a programming exercise I need to rewrite some existing methods and classes that make up a binary tree. (The method signatures and constructors have to stay the same). Somehow I don't really seem to understand what I have done here.
Does the toString method have to public because it overwrites the Object class's toString method? And how can I avoid the nulls from being returned?
Here is the code I have come to so far:
Tree Class
Node root = null;
void addNode(int val) {
Node newNode = new Node(val);
root = newNode.addNode(root, val);
}
Node Class
Node(int val) {
val = val;
left = null;
right = null;
}
Node addNode(Node focusNode, int newNodeVal) {
if (focusNode == null)
return this;
if (newNodeVal == focusNode.val)
return focusNode;
if (newNodeVal < focusNode.val)
focusNode.left = this.addNode(focusNode.left, newNodeVal);
else
focusNode.right = this.addNode(focusNode.right, newNodeVal);
return focusNode;
}
public String toString() {
return this.left + " " + this.val + " " + this.right;
}
Use a StringBuilder to store the String representation of the node and append the data of the children nodes only in the specific node is not null. Here's an example using infix navigation on the nodes:
public String toString() {
StringBuilder sb = new StringBuilder();
if (this.left != null) {
sb.append(this.left);
sb.append(' ');
}
sb.append(this.val);
if (this.right != null) {
sb.append(' ');
sb.append(this.right);
}
return sb.toString();
}
public String toString() {
if(this.left==null){
return this.val + this.right;
} else if (this.right==null){
return this.left + this.val;
} else if (this.left == null && this.right == null){
return "";
} else {
return this.left + " " + this.val + " " + this.right;
}
}
You assign your nodes to null to start, and your toString method assumes that they have been altered. Imagine a tree where you added 5, then 3. Then called toString on the tree. It will try to print the node, 5 is the value, left is 3, right is null. When you try to call
return this.left + " " + this.val + " " + this.right;
You are saying to print
3 5 NULL
You can initialize left and right with an empty Node object (with no val) and when you print it you will see null as the val of an empty Node:
Node(Integer val) {
this.val = val;
left = new Node(null);
right = new Node(null);
}
This only works if you make val an Integer.
There is also a bug in your code:
val = val will leave this.val untouched. You have to use this.val = val;
toString() is overridden not overwritten. It has to return a String and you can't really avoid nulls if your Node is a leaf.
What you can do is writing toString() in a way it can be meaningful to have a null as val like this:
public String toString() {
return "#{val = " + val + ", left = " + left + ", right = " + right + "}"
}
Please note that this will traverse your tree recursively so to print your tree you only have to call root.toString().