In the class containing the main function, define a function call createTree(String strKey). Giving a string of integers (separated by a space character), this function will create a BST tree with the keys of integers following the input string.
Example: Given a string s = "30 20 40". Calling the function createTree(s) to create a binary seach tree: root = 30, root.left = 20, root.right = 40.
Below is my code:
Node.java
public class Node {
Integer key;
Node left, right;
public Node(Integer key){
this.key = key;
this.left = this.right = null;
}
}
BST.java
public class BST {
private Node root;
public BST(){
this.root = null;
}
public Node getRoot(){
return this.root;
}
public Node insert(Node x, Integer key){
if (x == null){
return new Node(key);
}
int cmp = key.compareTo(x.key);
if (cmp < 0){
x.left = insert(x.left,key);
}
else if (cmp > 0){
x.right = insert(x.right,key);
}
else {
x.key = key;
}
return x;
}
}
Test.java
public class Test {
public static BST createTree(String strKey){
String[] spl = strKey.split(" ");
BST tree = new BST();
Node root = null;
for (int i=0; i<spl.length; i++){
Integer key = Integer.parseInt(spl[i]);
tree.insert(root,key);
}
return tree;
}
public static void main(String[] args){
String s = "20 30 40";
BST tree = createTree(s);
System.out.println(tree.getRoot());
}
}
The result is also null (the root is null) and I don't know the reason why the key is not inserted into the tree. Hope you guys can help me to solve this problem. Thanks a lot
if (x == null){
return new Node(key);
}
The returned node is not assigned to the root in the BST class. Also, you have a root in the createTree method.
You can change it to include an overloaded insert function which takes only the integer to insert and make the existing one private.
private Node insert(Node x, Integer key){
//your existing code
}
public void insert(Integer key) {
this.root = insert(this.root, key);
}
With this, the root will be updated when it is created the first time.
From createTree call the one argument insert method.
public static BST createTree(String strKey) {
String[] spl = strKey.split(" ");
BST tree = new BST();
for (int i = 0; i < spl.length; i++) {
Integer key = Integer.parseInt(spl[i]);
tree.insert(key);
}
return tree;
}
Related
The BST is as follows:
50 (Root 1)
/ \
40 80 (Root 2)
/ \
20 41
As you can see there are 2 root's that I am dealing with. I have tried the following code which does return the height of the tree from ROOT 1. I don't quite exactly know how to return the height from ROOT 2.
Any help on how to solve would be appreciated.
// Java program to find height of tree
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
int maxDepth(Node node)
{
if (node == null)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node.left);
int rDepth = maxDepth(node.right);
/* use the larger one */
if (lDepth > rDepth)
return (lDepth + 1);
else
return (rDepth + 1);
}
}
/* Driver program to test above functions */
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
}
Your function for finding max depth seems like to work correctly. So fixing this issue is pretty simple.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
The above line prints out the height of the tree starting at the root. But if you were to start at "root 2" as you call it you would need to modify this line to start at the correct node.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root.right));
Adding an item to a Tree class should be made through a insert method.
And we can make the Node class private, it is used only by BinaryTree class.
A better data structure for a tree should be like the following, which has public insert and height methods.
public class BinaryTree {
private class Node {
private int value;
private Node left;
private Node right;
private Node(int value) {
this.value = value;
}
}
private Node root;
public void insert(int item) {
var node = new Node(item);
if (root == null) {
root = node;
return;
}
var current = root;
while (true) {
if (item < current.value) {
if (current.left == null) {
current.left = node;
break;
}
current = current.left;
} else {
if (current.right == null) {
current.right = node;
break;
}
current = current.right;
}
}
}
public int height() {
return height(root);
}
private int height(Node root) {
if (root == null)
return -1;
if (isLeaf(root))
return 0;
return 1 + Math.max(height(root.left), height(root.right));
}
private boolean isLeaf(Node node) {
return node.left == null && node.right == null;
}
}
And to use it, just add some values, and print the height.
It is way easier to insert an item with this tree class.
BinaryTree tree = new BinaryTree();
tree.insert(50);
tree.insert(40);
tree.insert(80);
tree.insert(20);
tree.insert(41);
System.out.println(tree.height());
I am trying to insert in a binary search tree using recursion and then print it preorderly using this specific code, but I have only root as output,why?Is this because each time stack(after each call) is popping off thus removing new nodes?(This is a java code)
class node{
int data;
node left;
node right;
node(int key){
data = key;
left = right = null;
}
}
class bst{
node root;
node temp;
node last;
bst(){
root = null;
}
bst(int key){
root = new node(key);
}
void Insert(node r,int value){
temp = r;
if(temp == null){
if(root == null){
root = new node(value);
root.data = value;
return;
}
temp = new node(value);
temp.data = value;
return;
}
else{
if(value > temp.data){
Insert(temp.right,value);
return;
}
else{
Insert(temp.left,value);
return;
}
}
}
}
class test{
static void in_order(node root){
if(root == null){
return;
}
in_order(root.left);
System.out.println(root.data+" ");
in_order(root.right);
}
public static void main(String[] args){
bst tree = new bst();
tree.Insert(tree.root,45);
tree.Insert(tree.root,39);
tree.Insert(tree.root,12);
tree.Insert(tree.root,59);
test.in_order(tree.root);
}
}
The reason you are only getting a single integer for an output is because the first Insert call correctly adds the element to the tree, but subsequent calls fail because you overwrite the data member temp to null when you recursively insert to the left or right. Thus the second branch of your first if statement never gets executed.
You don't actually need the variable temp here. A common convention is to have a private, recursive member function that takes the root of the tree as a parameter returns the modified tree, and assign the return value to root in a public member function.
public void Insert(int value) {
root = Insert(root, value);
}
private node Insert(node r, int value) {
if (r == null) {
r = new node(value);
}
else if (value > r.data) {
r.right = Insert(r.right, value);
}
else {
r.left = Insert(r.left, value);
}
return r;
}
This means that you only have to call it like tree.Insert(x).
I've been working on this coding problem and have been able to successfully get the depth of each leaf node into a hash set. What I'm trying to do is determine if the difference in depth is of a leaf node is greater than one BEFORE that depth is added to the hash set. I don't want to put all of the leaf nodes in the hash set and use two for loops to check if there is a difference in depth greater than one. In my code below, the int variable count represents depth.
The problem is my code always returns true. Something is wrong with the code where is checks the difference in depths/count for each leaf node. Code is below. I'm trying to keep this method in O(n) time, and avoid O(n^2).
The depths of the four leaf nodes in this tree are : 3, 2, 2, 5
import java.util.*;
public class cakeEightWeekly {
static int count = 0;
public static class Node {
public int value;
public Node leftChild;
public Node rightChild;
public Node(int value) {
this.value = value;
}
public void setLeft(Node leftValue) {
this.leftChild = leftValue;
}
public void setRight(Node rightValue) {
this.rightChild = rightValue;
}
public Node getRight() {
return rightChild;
}
public Node getLeft() {
return leftChild;
}
}
public static boolean isBalanced(Node root) {
HashSet < Integer > hset = new HashSet < Integer > ();
if (root != null) {
count++;
isBalanced(root.getLeft());
isBalanced(root.getRight());
count--;
if (root.getLeft() == null && root.getRight() == null) {
if (!hset.isEmpty()) {
for (int x: hset) {
if ((x - count) < 0) {
int sum = count - x;
if (sum > 1) {
return false;
}
} else if ((x - count) > 1) {
return false;
}
}
hset.add(count);
} else {
hset.add(count);
}
}
}
return true;
}
public static void main(String[] args) {
Node One = new Node(1);
Node Two = new Node(2);
Node Three = new Node(3);
Node Four = new Node(4);
Node Five = new Node(5);
Node Six = new Node(6);
Node Seven = new Node(7);
Node Eight = new Node(8);
Node Nine = new Node(9);
Node Ten = new Node(10);
Node Eleven = new Node(11);
Five.setLeft(Three);
Five.setRight(Seven);
Three.setLeft(Two);
Three.setRight(Four);
Two.setLeft(One);
Seven.setLeft(Six);
Seven.setRight(Eight);
Eight.setRight(Nine);
Nine.setRight(Ten);
Ten.setRight(Eleven);
System.out.print(isBalanced(Five));
}
}
I am creating a program for class that sorts a 2D array faster than my teacher's implementation.
I decided to put the data into a BST and then remove each minimum element and put it into a new sorted array. However, I've been having trouble with it so I wrote it using int instead of T, when I did this the program worked!
However, now that I converted it to use the generic type T, it is no longer sorting correctly. The class below is what I've written and inherits the method sort(T[][] input) from my teacher's class HybridSort.
I believe my problem lies somewhere in the way I've been dealing with the generic type T and treating it as an int (I use x.compareTo(y) so I don't believe that is the problem). I can also post the code I wrote using int if necessary. Thanks!
public class ***<T extends Comparable<T>> implements HybridSort<T> {
public class BST {
public T value;
public BST left;
public BST right;
public BST root;
public BST() {
this.value = null;
this.left = null;
this.right = null;
}
public BST(T value, BST left, BST right) {
this.value = value;
this.left = left;
this.right = right;
}
public void insert(T value) {
root = insert(root, new BST(value, null, null));
this.value = root.value;
this.left = root.left;
this.right = root.right;
}
public BST insert(BST parent, BST newIndex) {
if (parent == null) return newIndex;
else if (newIndex.value.compareTo(parent.value) != 1) parent.left = insert(parent.left, newIndex);
else if (newIndex.value.compareTo(parent.value) > 0) parent.right = insert(parent.right, newIndex);
return parent;
}
public T removeMin() {
BST current = root;
BST parent = root;
while (current.left != null) {
parent = current;
current = current.left;
}
parent.left = current.left;
return current.value;
}
}
#SuppressWarnings("unchecked")
public T[] sort(T[][] input) {
BST bst = new BST();
int size = Arrays.stream(input).mapToInt(t -> t.length).sum();
T[] output = (T[])Array.newInstance(input[0][0].getClass(), size);
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[0].length; j++) {
bst.insert(input[i][j]);
}
}
for (int i = 0; i < output.length; i++) {
output[i] = (T)(Integer)bst.removeMin();
}
return output;
}
}
Basically, I am implementing an AVL tree by reading a set of integers from a text file and then populate the tree by using the add() method. Also, the program is supposed to print in order the set of integers.
As I run the program, a StackOverflowError pops up. I think that this error is being triggered due to something malfunctioning in the add() method.
I would really appreaciate if someone helps me as I am new to this type of programming.
This is part of the Main Class:
public static void main(String[] args) throws FileNotFoundException
{
AVL s1 = new AVL();
Scanner file = new Scanner(new File("C:\\Users\\Dell\\Desktop\\integers.txt"));
while(file.hasNext())
{
// String str = file.next();
//int b = Integer.parseInt(str);
int b = file.nextInt();
s1.add(b);
}
v1.PrintInOrder(v1.root);
These are the add() and PrintInOrder() methods:
public boolean add(int key)
{
root = add(root, key);
return true;
}
private Node add(Node b1, int key)
{
if(b1 == null)
{
return new Node(key);
}
if(key < b1.element){
b1.left = add(b1.left, key);
}
else
{
b1.right = add(b1.right, key);
}
int Left_Height = getHeight(b1.left);
int Right_Height = getHeight(b1.right);
// a height imbalance requires that two subtrees differ by two
if(Math.abs(LeftHeight - RightHeight )== 2)
return Balance(n1);
else
{
n1.ResetHeight();
return b1;
}
}
public void PrintInOrder(Node b1){
if(b1 != null){
PrintInOrder(b1.left);
System.out.println(b1.element);
PrintInOrder(b1.right);
}
}
This is the Node class:
public class Node {
Node left;
Node right;
int element;
int height;
public Node(int keys){
this(keys, null, null);
}
public Node(int d, Node right1, Node left1){
element = d;
height = 0;
left = left1;
right = right1;
}
// This method recalculates the height if the right or left subtrees have been altered
public void ResetHeight(){
int LeftHeight = AVL.getHeight(left);
int RightHeight = AVL.getHeight(right);
height = 1 + Math.max(LeftHeight,RightHeight);
}
Since stack overflows commonly occur in recursion. Use your IDE and set a break at locations where you have done recusion, then debug. Step through it.