I'm working on a binary search tree and try to write a method for creating minimum BST from an array values. However, it's not working successfully. Where I'm making mistake ? It should print values in ascending order using inOrderTraverseTree method. I keep some additional methods and can delete if may feel irrelevant.
I updated the code in question, but, I still need to get the root Node to call the inOrderTraversal (Node root) method.
BinaryTree.java
class Node {
int key;
Node leftChild;
Node rightChild;
Node(int key) {
this.key = key;
}
Node (){}
public String toString() {
return "\n"+key+" ";
}
}
public class BinaryTree {
Node root;
BinaryTree (){
root = null;
}
public void addNode(int key) {
Node newNode = new Node(key);
// If there is no root this becomes root
if (root == null) {
root = newNode;
}
else {
// Set root as the Node we will start
// with as we traverse the tree
Node focusNode = root;
Node parent;
while (true) {
parent = focusNode;
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return; // All Done
}
} // end of if
else {
focusNode = focusNode.rightChild;
if (focusNode == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
// get the height of binary tree
public int height(Node root) {
if (root == null)
return -1;
Node focusNode = root;
int leftHeight = focusNode.leftChild != null ? height( focusNode.leftChild) : 0;
int rightHeight = focusNode.rightChild != null ? height( focusNode.rightChild) : 0;
return 1 + Math.max(leftHeight, rightHeight);
}
// METHODS FOR THE TREE TRAVERSAL
// inOrderTraverseTree : i) X.left ii) X iii) X.right
public void inOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
inOrderTraverseTree(focusNode.leftChild);
// System.out.println(focusNode);
System.out.print( focusNode );
inOrderTraverseTree(focusNode.rightChild);
}
// System.out.println();
}
// preOrderTraverseTree : i) X ii) X.left iii) X.right
public void preorderTraverseTree(Node focusNode) {
if (focusNode != null) {
System.out.println(focusNode);
preorderTraverseTree(focusNode.leftChild);
preorderTraverseTree(focusNode.rightChild);
}
}
// postOrderTraverseTree : i) X.left ii) X.right iii) X
public void postOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
preorderTraverseTree(focusNode.leftChild);
preorderTraverseTree(focusNode.rightChild);
System.out.println(focusNode);
}
}
// END
public Node findNode(int key) {
Node focusNode = root;
while (focusNode.key != key) {
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return null;
}
return focusNode;
}
public boolean remove(int key) {
Node focusNode = root;
Node parent = root;
boolean isItALeftChild = true;
// we will remove the focusNode
while (focusNode.key != key) {
parent = focusNode;
if (key < focusNode.key) {
isItALeftChild = true;
focusNode = focusNode.leftChild;
}
else {
isItALeftChild = false;
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return false;
}
// no child
if (focusNode.leftChild == null && focusNode.rightChild == null) {
if (focusNode == root)
root = null;
else if (isItALeftChild)
parent.leftChild = null;
else
parent.rightChild = null;
}
// one child ( left child )
else if (focusNode.rightChild == null) {
if (focusNode == root)
root = focusNode.leftChild;
else if (isItALeftChild)
parent.leftChild = focusNode.leftChild;
else
parent.rightChild = focusNode.leftChild;
}
else if (focusNode.leftChild == null) {
if (focusNode == root)
root = focusNode.rightChild;
else if (isItALeftChild)
parent.leftChild = focusNode.rightChild;
else
parent.rightChild = focusNode.rightChild;
}
// two children exits
else {
// replacement is the smallest node in the right subtree
// we neeed to delete the focusNode
Node replacement = getReplacementNode(focusNode);
if (focusNode == root)
root = replacement;
else if (isItALeftChild)
parent.leftChild = replacement;
else
parent.rightChild = replacement;
replacement.leftChild = focusNode.leftChild;
}
return true;
}
public Node getReplacementNode(Node replacedNode) {
Node replacementParent = replacedNode;
Node replacement = replacedNode;
Node focusNode = replacedNode.rightChild;
// find the smallest node of the right subtree of the node to be deleted
while (focusNode != null) {
replacementParent = replacement;
replacement = focusNode;
focusNode = focusNode.leftChild;
}
// exit when the focusNode is null
// the replacement is the smallest of the right subtree
if (replacement != replacedNode.rightChild) {
replacementParent.leftChild = replacement.rightChild;
replacement.rightChild = replacedNode.rightChild;
}
return replacement;
}
private void createMinimalBST(int arr[], int start, int end, Node newNode){
if ( end <= start )
return;
int mid = (start + end) / 2;
newNode.key = arr[mid];
if ( root == null ){
root = newNode;
}
System.out.println("new node = "+ newNode );
if (start <= mid-1) {
newNode.leftChild = new Node();
createMinimalBST(arr, start, mid - 1, newNode.leftChild);
}
if (mid+1 <= end) {
newNode.rightChild = new Node();
createMinimalBST(arr, mid + 1, end, newNode.rightChild);
}
// System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}
public void createMinimalBST(int array[]) {
Node n = new Node();
createMinimalBST(array, 0, array.length - 1, n);
}
public static void main(String[] args) {
int[] myArr = { 1,2,3,4,5,6,7,8,9 }; // sortedArrayToBST
BinaryTree myTr = new BinaryTree();
// Node n = BinaryTree.createMinimalBST(myArr);
myTr.createMinimalBST(myArr);
// System.out.println("The root is = "+myTr.root);
// myTr.inOrderTraverseTree(myTr.root);
System.out.println();
myTr.inOrderTraverseTree(myTr.root);
}
}
You need to assign the result of createMinimalBST() to a variable.
This method returns a Node:
public Node createMinimalBST(int array[]) {...}
However, in the main, ...
myTr.createMinimalBST(myArr);
you calls to the method but no variable try to hold the result.
Also, You may want to make createMinialBST to be public static and call it like this:
myTr = BinaryTree.createMinimalBST(myArr);
Beside, there are 2 more ways to make this work:
1) move createMinimalBST() into Node, so that the recursion can occur while the key will be setting in-place.
private void createMinimalBST(int arr[], int start, int end){
int mid = (start + end) / 2;
this.key = arr[mid];
System.out.println("new node = "+n);
if (start <= mid-1) {
this.leftChild = new Node();
this.leftChild.createMinimalBST(arr, start, mid - 1);
}
if (mid+1 <= end) {
this.rightChild = new Node();
this.rightChild.createMinimalBST(arr, mid + 1, end);
}
System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}
2) If you want that method stays in BinaryTree, you can consider to pass in the Node as a parameter into createMinimalBST() ilke createMinimalBST(arr, node);
private void createMinimalBST(int arr[], int start, int end, Node newNode){
int mid = (start + end) / 2;
newNode.key = arr[mid];
System.out.println("new node = "+n);
if (start <= mid-1) {
newNode.leftChild = new Node();
createMinimalBST(arr, start, mid - 1, newNode.leftChild);
}
if (mid+1 <= end) {
newNode.rightChild = new Node();
createMinimalBST(arr, mid + 1, end, newNode.leftChild);
}
System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}
Related
I'm having trouble implementing an AVL tree in java and would appreciate your help,
preferably by explaining what's wrong with my code (I've seen different implementations and would like to figure out what's wrong with mine).
public class AVLTree<T> {
public AVLNode<T> root;
int size;
//constructor
public AVLTree() {
root = null;
size = 0;
}
public void add(T obj) {
//initialize the new node
AVLNode<T> node = new AVLNode<T>(obj);
//if the tree is empty than our new node will serve as a root
if(root == null)
{
root = node;
size++;
return;
}
add(root, node);
}
private void checkViolations(AVLNode<T> node) {
int dif = Math.abs(height(node.left) - height(node.right)) ;
//there's a violation at our level
if(dif > 1)
{
rebalance(node);
}
//if we're at the root, tree is balances(AVL)
if(node.parent == null) return;
//we're not at the top, check parent
checkViolations(node.parent);
}
private void rebalance(AVLNode<T> node) {
//right subtree is bigger than left subtree
if(height(node.right) - height(node.left) > 1)
{
//problem is right-right
if(height(node.right.right) > height(node.right.left))
node = leftRotation(node);
//problem is right-left
else
node = rightLeftRotation(node);
}
//left subtree is bigger than right subtree
else
{
//problem is left-left
if (height(node.left.left) > height(node.left.right))
node = rightRotation(node);
//problem is left-right
else
node = leftRightRotation(node);
}
if (node.parent == null)
root = node;
}
private AVLNode<T> rightLeftRotation(AVLNode<T> node) {
node.right = rightRotation(node.right);
return leftRotation(node);
}
private AVLNode<T> leftRightRotation(AVLNode<T> node){
node.left = leftRotation(node.left);
return rightRotation(node);
}
private AVLNode<T> rightRotation(AVLNode<T> node) {
AVLNode<T> temp = node.left;
node.left = temp.right;
temp.parent = node.parent;
temp.right = node;
node.parent = temp;
return temp;
}
private AVLNode<T> leftRotation(AVLNode<T> node) {
AVLNode<T> temp = node.right;
node.right = temp.left;
temp.parent = node.parent;
temp.left = node;
node.parent = temp;
return temp;
}
private int height(AVLNode<T> node) {
//base case
if(node == null) return 0;
return 1 + (Math.max(height(node.left), height(node.right)));
}
private void add(AVLNode<T> parent, AVLNode<T> newNode) {
if(((Comparable<T>)newNode.data).compareTo(parent.data) > 0)
{
if(parent.right == null)
{
parent.right = newNode;
newNode.parent = parent;
size++;
}
else add(parent.right, newNode);
}
else
{
if(parent.left == null)
{
parent.left = newNode;
newNode.parent = parent;
size++;
}
else add(parent.left, newNode);
}
checkViolations(newNode);
}
}
I'm trying to add the next numbers in this order (left to right): 1,2,3,4,5
up until 4, everything seems to go great.
Thank you
I have written a Code for AVL Tree Insertion but when I try to print the value of Root Node it always returns Null. I am unable to understand the reason.Anyone who can solve this problem? I have tried many times but I could not resolve the problem. I am confused. I hope that someone from here will help in the case of resolving the problem I have as I am sure there are high level of experts here.
public class AVLTreeMethods {
public Node root = null;
public int height(Node node){
if (node == null)
return 0;
return node.height;
}
public int max(Node node1, Node node2){
if (node1.height > node2.height)
return node1.height;
return node2.height;
}
public Node rotateRight(Node node){
Node newNode = node.left;
node.left = newNode.right;
newNode.right = node;
node.height = max(node.left,node.right) + 1;
newNode.height = max(newNode.left, newNode.right) + 1;
return newNode;
}
public Node rotateleft(Node node){
Node newNode = node.right;
node.right = newNode.left;
newNode.left = node;
node.height = max(node.left,node.right) + 1;
newNode.height = max(newNode.left, newNode.right) + 1;
return newNode;
}
public Node AVLINSERT(int data, Node root){
if (root == null){
return new Node(data);
}
else if (data > root.data){
root.left = AVLINSERT(data, root.left);
}
else if (data < root.data){
root.right = AVLINSERT(data, root.right);
}
int balance = height(root.left) - height(root.right);
if (balance > 1){
if (height(root.left.left) > height(root.left.right)){
return rotateRight(root);
}
else {
root.left = rotateleft(root.left);
return rotateRight(root);
}
}
if (balance < -1){
if (height(root.right.right) > height(root.right.left)){
return rotateleft(root);
}
else
root.right = rotateRight(root);
return rotateleft(root);
}
root.height = 1 + max(root.left, root.right);
return root;
}
public void inorderPrinting(Node root){
inorderPrinting(root.left);
System.out.println(root.data);
inorderPrinting(root.right);
}
public void callingAVLInserting(int data){
AVLINSERT(data,root);
}
public void callinInorderPrinting(){
inorderPrinting(root);
}
}
Just by looking at your code, you have initialised the root to null however, you do not have any constructor that initializes it.
So try add something of the sort.
public class AVLTreeMethods {
public Node root = null;
//add the following
public AVLTreeMethods() {
//initialize your root appropriately e.g.
this.root = new Node(//pass in some data e.g 0)
}
...rest of your code
}
I am supposed to return the oldest element in a priority min queue along with said element. I have to use nodes, arrays are optional. This is what I got so far but I have an null pointer error on line 20 and i don't know how to fix it. Please help
public class MinHeap {
public static int timeStamp = 0;
public static int ts = 0;
public static int maxTime = 0;
public static Node root;
public MinHeap(){
this.root = null;
}
public static void insert(int id, int ts){
timeStamp++;
Node newNode = new Node(id);
if(root==null){
root = newNode;
}
Node current = root;
Node parent = null;
while(true){
parent = current;
if(id < current.data){
current = current.left;
if(current==null){
parent.left = newNode;
}
}else{
current = current.right;
if(current==null){
parent.right = newNode;
}
}
}
}
public static Node delete(int x, Node n){
timeStamp++;
if(n==null)
return n;
if(x == n.data){
if(n.left == null && n.right == null){
return null;
}else if(n.left == null){
n.right = delete(x, n.right);
return n;
}else if(n.right == null){
n.left = delete(x, n.left);
return n;
}else{
Node tempNode = findMin(n.right);
n.right = delete(tempNode.data, n.right);
n.data = tempNode.data;
return n;
}
}
if(x < n.data){
n.left = delete(x, n.left);
return n;
}else{
n.right = delete(x, n.right);
return n;
}
}
public static void display(Node root){
if(root!=null){
display(root.left);
System.out.print(" " + root.data);
display(root.right);
}
}
public static Node findMin(Node n){
if(n == null){
return null;
}
if(n.left == null){
return n;
}
return findMin(n.left);
}
public static int maxAge(){
int currentAge = 0;
currentAge = timeStamp - ts;
if(currentAge > maxTime)
maxTime = currentAge;
return maxTime;
}
public static void main(String [] arg){
MinHeap min = new MinHeap();
min.insert(1, ts = 0);
min.insert(2, ts = 1);
min.insert(3, ts = 2);
min.insert(4, ts = 4);
min.delete(1, root);
min.delete(2, root);
min.delete(3, root);
min.delete(4, root);
min.maxAge();
}
}
class Node{
int data;
Node left;
Node right;
public Node(int data){
this.data = data;
left = null;
right = null;
}
}
Your insert is broken. You forgot to break after finding the insert point, and you're not checking for the case where the key is already in the tree.
while (true) {
parent = current;
if (id < current.data) {
current = current.left;
if (current == null) {
parent.left = newNode;
// Break after insert
break;
}
} else if (id > current.data) {
current = current.right;
if (current == null) {
parent.right = newNode;
// Break after insert
break;
}
} else {
// Key exists.
break;
}
}
I was tasked to create a tree that stores fibonacci numbers. I previously recycled some code used to create a tree full of names and the key for each node. I can't seem to figure out why when I perform any traversal it doesn't print out the key of the node and value stored. I feel like I am missing something so simple. Well thank you for your time! OR maybe I am misunderstanding the assignment. I do not expect a direct answer since this is pertaining to my education!
original instructions
Create a binary tree that stores your calls. How many calls will each internal node make? How many internal nodes will you have for a recursive version of the solution? Now, how big is that number? What if you call 5 ānā and think of Fib(n). What is the runtime complexity of your solution? Do you think you can do better if you simply do away with the recursion and calculate the Fibonacci series iteratively? Write a non-recursive solution and perform a similar analysis on it. How many lines of code would you execute in terms of ānā? Is it better or worse? Why do you think this is true?
class Node {
int key;
int value;
Node leftChild;
Node rightChild;
Node(int key, int value) {
this.key = key;
this.value = value;
}
}
and this is the rest
package bigobinarytree;
public class BigOBinaryTree {
Node root;
public void addNode(int key, int value) {
Node newNode;
newNode = new Node(key, value);
if (root == null) {
root = newNode;
}
else {
Node focusNode = root;
Node parent;
while (true) {
parent = focusNode;
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return;
}
}
else
{
focusNode = focusNode.rightChild;
if (focusNode == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
public void inOrderTraverse(Node focusNode) {
if (focusNode != null) {
inOrderTraverse(focusNode.leftChild);
System.out.println(focusNode);
inOrderTraverse(focusNode.rightChild);
}
}
public void preorderTraverse(Node focusNode) {
if (focusNode != null) {
System.out.println(focusNode);
preorderTraverse(focusNode.leftChild);
preorderTraverse(focusNode.rightChild);
}
}
public void postOrderTraverse(Node focusNode) {
if (focusNode != null) {
postOrderTraverse(focusNode.leftChild);
postOrderTraverse(focusNode.rightChild);
System.out.println(focusNode);
}
}
public Node findNode(int key) {
Node focusNode = root;
while (focusNode.key != key) {
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return null;
}
return focusNode;
}
public Node findValue(int value) {
Node focusNode = root;
while (focusNode.value != value) {
if (value != focusNode.value) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return null;
}
return focusNode;
}
public boolean remove(int key) {
Node focusNode = root;
Node parent = root;
boolean isItALeftChild = true;
while (focusNode.key != key) {
parent = focusNode;
if (key < focusNode.key) {
isItALeftChild = true;
focusNode = focusNode.leftChild;
} else {
isItALeftChild = false;
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return false;
}
if (focusNode.leftChild == null && focusNode.rightChild == null) {
if (focusNode == root)
root = null;
else if (isItALeftChild)
parent.leftChild = null;
else
parent.rightChild = null;
}
else if (focusNode.rightChild == null) {
if (focusNode == root)
root = focusNode.leftChild;
else if (isItALeftChild)
parent.leftChild = focusNode.leftChild;
else
parent.rightChild = focusNode.leftChild;
}
else if (focusNode.leftChild == null) {
if (focusNode == root)
root = focusNode.rightChild;
else if (isItALeftChild)
parent.leftChild = focusNode.rightChild;
else
parent.rightChild = focusNode.rightChild;
}
else {
Node replacement = getReplacementNode(focusNode);
if (focusNode == root)
root = replacement;
else if (isItALeftChild)
parent.leftChild = replacement;
else
parent.rightChild = replacement;
replacement.leftChild = focusNode.leftChild;
}
return true;
}
public Node getReplacementNode(Node replacedNode) {
Node replacementParent = replacedNode;
Node replacement = replacedNode;
Node focusNode = replacedNode.rightChild;
while (focusNode != null) {
replacementParent = replacement;
replacement = focusNode;
focusNode = focusNode.leftChild;
}
if (replacement != replacedNode.rightChild) {
replacementParent.leftChild = replacement.rightChild;
replacement.rightChild = replacedNode.rightChild;
}
return replacement;
}
public static void main(String[] args) {
BigOBinaryTree theTree = new BigOBinaryTree();
int fib1=1, fib2=1, nacci=1;
int key = 0;
for (int i=3; i <= 50; i++ ){
nacci = fib1 + fib2;
fib1 = fib2;
fib2 = nacci;
theTree.addNode(key, nacci);
key++;
}
System.out.println();
System.out.println("preorderTraverse");
System.out.println();
theTree.preorderTraverse(theTree.root);
System.out.println("___________________");
}
}
You were right, it was something simple, which is bittersweet. You've called
System.out.println(focusNode);
However, for Objects (like focusNode), System.out.println() automatically calls that Object's toString() method. For most Objects, that just means print out their Object ID, and also for most Objects, that's not super useful. Not for programs like this at least. The good news, though, is there are two fixes! First, you could override your Node's toString(). Like:
#Override
public String toString() {
return "Key:" + key + " Value:" + value;
}
You'd just put that in the Node class. Then, every time you called System.out.println(focusNode), under the hood it's actually printing the output of your toString() method in the Node class. Alternatively, instead using:
System.out.println(focusNode);
you could just use:
System.out.println("Key:" + focusNode.key + " Value:" + focusNode.value);
You invokes the preorder method in your main method.
if (focusNode != null) {
System.out.println(focusNode);
preorderTraverse(focusNode.leftChild);
preorderTraverse(focusNode.rightChild);
}
Does that give you any output? If you get some output, based on your code it will be only the standard toString() method of the focusNode object. If you want print out field values of the object like the key, you have to access these fields or overwrite the toString() Method. Like:
System.out.println(focusNode.key);
folks, I've implemented the code for counting the total number of Nodes in a binary tree and the method looks like the following:
public int countNodes(Node root){
int count = 0;
if(root == null){
System.out.println("The tree is empty!");
return -1;
}
else{
count = 1;
Node current = root;
if(current.leftChild != null){
count += countNodes(current.leftChild);
}
else if(current.rightChild != null){
count += countNodes(current.rightChild);
}
}
System.out.print("The total number of nodes in the tree is ");
return count;
}
The parameter of the method contains Node root but my question is when I try to run the method from the main class then what should I pass as a parameter??
what should I add inside the parameters here?:
int countNodes = tree1.countNodes("?????????????");
package BST;
public class Node {
int data;
Node leftChild;
Node rightChild;
public void displayNode(){
System.out.println("The data is " + this.data);
}
}
class Tree{
private Node root;
public Tree(){
this.root = null;
}
public Node find(int key){
Node current = root;
while(current.data != key){
if(key < current.data){
current = root.leftChild;
}
else{
current = root.rightChild;
}
if(current == null){
System.out.println("The Node contatining the key " + key + " does not exist!");
return null;
}
}
return current;
}
public void insert(int key){
Node newNode = new Node();
if(root == null){
root = newNode;
}
else{
Node current = root;
Node parent;
while(true){
parent = current;
if(current.data > key){
current = current.leftChild;
if(current == null){
parent.leftChild = newNode;
return;
}
}
else{
current = current.rightChild;
if(current == null){
parent.rightChild = newNode;
return;
}
}
}
}
}
public Node findMin(){
if(root == null){
System.out.println("The tree is empty!");
return null;
}
else{
Node current = root.leftChild;
Node last = root;
while(current != null){
last = current;
current = current.leftChild;
}
return last;
}
}
public Node findMax(){
if(root == null){
System.out.println("The tree is empty!");
return null;
}
else{
Node current = root.rightChild;
Node last = root;
while(current != null){
last = current;
current = current.rightChild;
}
return last;
}
}
public int countNodes(Node root){
int count = 0;
if(root == null){
System.out.println("The tree is empty!");
return -1;
}
else{
count = 1;
Node current = root;
if(current.leftChild != null){
count += countNodes(current.leftChild);
}
else if(current.rightChild != null){
count += countNodes(current.rightChild);
}
}
System.out.print("The total number of nodes in the tree is ");
return count;
}
Class MainTester
class MainTester{
public static void main(String[] args){
Tree tree1 = new Tree();
tree1.insert(1);
tree1.insert(2);
tree1.insert(3);
tree1.insert(4);
tree1.insert(5);
tree1.insert(6);
tree1.insert(7);
tree1.insert(8);
tree1.insert(9);
tree1.insert(10);
int countNodes = tree1.countNodes("?????????????");
}
}
You can use the root node of the tree. Basing from your example, you can get it from the method find()
int countNodes = tree1.countNodes(tree1.find(1));
You can also use other nodes like
int countNodes = tree1.countNodes(tree1.find(5));