I created a method that is suppose to balance a BinarySearchTree.
The instructions were that the balance method should update the tree so that it is balanced, meaning that the largest difference between subtree heights is no more than 1.
With the following process:
• Get an array of sorted values in the tree (we have a method that can do this)
• Assign the tree's root to the result of the buildTreeUtil helper method (described below)
• Call assignFirst to update the tree's "first" attribute
The buildTreeUtil(E[], int, int, BSTNode parent) helper method rebuilds the tree using a sorted list of values. Since it has this sorted list, it doesn't have to search for where to insert new values, so it doesn't (and shouldn't) call the add method. Instead, it selectively grabs values from the sorted list of values when adding new nodes. It's algorithm is as follows:
• If the "start" parameter is greater than the "end" parameter, the recursion should stop
• Create a new node storing the middle element in the list
• Assign the new node's left reference to a recursive call using the left half of the list
• Assign the new node's right reference to a recursive call using the right half of the list
Here is the following code:
public void balance()
{
this.root = buildTreeUtil(toArray(), 0, size(), first);
assignFirst();
}
private BSTNode<E> buildTreeUtil(E[] values, int start, int end, BSTNode<E> parent)
{
if(start > end)
{
return null;
}
int mid = (start + end)/2;
BSTNode<E> node = new BSTNode<E>(values[mid]);
node.left = buildTreeUtil(values, start, mid - 1, parent.left);
node.right = buildTreeUtil(values, mid + 1, end, parent.right);
return node;
}
private void assignFirst()
{
if (root.left != null)
{
first.left = first;
}
else
{
first = root;
}
}
#SuppressWarnings("unchecked")
public E[] toArray()
{
ArrayList<E> aList = new ArrayList<E>();
E[] arr = (E[]) new Comparable[this.numElements];
toArray(this.root, aList);
return aList.toArray(arr);
}
private void toArray(BSTNode<E> node, List<E> aList)
{
if (node != null)
{
toArray(node.left, aList);
aList.add(node.data);
toArray(node.right, aList);
}
}
This is just the rest of my code cut short so there is some valuable background information.
public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;
private BSTNode<E> first;
// post: constructs an empty search tree
public BinarySearchTree()
{
this.root = null;
this.numElements = 0;
}
public class Iterator
{
private BSTNode<E> currentNode;
public Iterator()
{
currentNode = first;
}
public boolean hasNext()
{
return currentNode != null;
}
public E next()
{
E value = currentNode.data;
currentNode = currentNode.next;
return value;
}
}
private static class BSTNode<E>
{
public E data;
public BSTNode<E> left;
public BSTNode<E> right;
public BSTNode<E> parent;
public BSTNode<E> next;
public BSTNode(E data)
{
this(data, null, null, null, null);
}
public BSTNode(E data, BSTNode<E> left, BSTNode<E> right, BSTNode<E> parent, BSTNode<E> next)
{
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
this.next = next;
}
}
}
I'm not sure where the error occurs or if I'm assigning the incorrect values inside the parameters for buildTreeUtil.
Related
For an assignment, I need to create an iterable that contains all keys for a symbol table backed by a binary search tree. I'm familiar with how to do this for a linked list, but can't seem to find any examples online about how to do this for a BST. For a linked list, for example, I'd use something like this:
public Iterable<Key> keys() {
Queue<Key> queue = new Queue<Key>();
for (Node x = first; x != null; x = x.next)
queue.enqueue(x.key);
return queue;
}
But I'm not quite sure how to convert that so it holds all keys for my BST. Can someone provide guidance or a link to a source that covers this topic?
If you want to traverse left first, you can implement it using a stack.
static class Node<T> {
T value;
Node<T> left, right;
Node(T value, Node<T> left, Node<T> right) {
this.value = value;
this.left = left;
this.right = right;
}
}
and
static class BST<T> implements Iterable<T> {
Node<T> root;
public BST(Node<T> root) {
this.root = root;
}
#Override
public Iterator<T> iterator() {
return new Iterator<>() {
Deque<Node<T>> stack = new LinkedList<>();
{ pushAllLeft(root); }
private void pushAllLeft(Node<T> node) {
for ( ; node != null; node = node.left)
stack.push(node);
}
#Override
public boolean hasNext() {
return !stack.isEmpty();
}
#Override
public T next() {
Node<T> current = stack.pop();
pushAllLeft(current.right);
return current.value;
}
};
}
}
and
public static void main(String[] args) {
BST<Integer> bst = new BST<>(
new BST.Node<>(3,
new BST.Node<>(1,
new BST.Node<>(0, null, null),
new BST.Node<>(2, null, null)),
new BST.Node<>(5,
new BST.Node<>(4, null, null),
new BST.Node<>(6, null, null))));
for (int n : bst)
System.out.println(n);
}
output:
0
1
2
3
4
5
6
I am implementing a recursive in-order traversal for a binary tree and want to save the data for each node in a list inOrderList which is modified only by this method. defining the list in the inOrder function is a problem because it is recursive. not sure where to declare the list, maybe I should change the structure of the project, how should I implement this functionality with best practices?
class TreeNode {
private TreeNode left;
private TreeNode right;
private Integer data;
public TreeNode(TreeNode left, TreeNode right, Integer data) {
this.left = left;
this.right = right;
this.data = data;
}
// getters..
}
class TreeOperations {
public static void inOrder(TreeNode node) {
if (node == null) return;
inOrder(node.getLeft());
inOrderList.add(node.getData()); // where to define ArrayList<Integer> inOrderList?
inOrder(node.getRight());
}
// many more methods not using inOrderList
}
Have a helper function which does the actual recursion, i.e.:
public static List<Integer> inOrder(TreeNode node) {
final List<Integer> inOrderList = new ArrayList<Integer>();
inOrderHelper(node, inOrderList);
return inOrderList;
}
private static void inOrderHelper(TreeNode node, List<Integer> inOrderList) {
if (node == null) return;
inOrderHelper(node.getLeft(), inOrderList);
inOrderList.add(node.getData());
inOrderHelper(node.getRight(), inOrderList);
}
I am writing a program where i have to create a Double linked list full of nodes which user can insert with own values.I have methods to insert the new node into different parts of the list(front, in position,tail). Each node has two informations, one String and the oder INT (both are set by user after creating a new node.
My problem here is how can i set the first information as String, (in the exaple i give there is the version with bot elements INT, but the first one must be string and this is where i need help)
public void insertInFirstPosition(int information,int key) {
Node n = new Node(information,key, null, null);
if (head == null) {
n.setLinkNext(n);
n.setLinkPrev(n);
head = n;
tail = head;
} else {
n.setLinkPrev(tail);
tail.setLinkNext(n);
head.setLinkPrev(n);
n.setLinkNext(head);
head = n;
}
size++;
}
HERE IS THE NODE CLASS `
public class Node {
private int data;
private int informazione;
private Node next, prev;
/* Constructor */
public Node() {
next = null;
prev = null;
data = 0;
informazione = 0;
}
public Node(int i,int k, Node n, Node p) {
data = i;
informazione = k;
next = n;
prev = p;
}
/* Function to set link to next node */
public void setLinkNext (Node n) {
next = n;
}
/* Function to set link to previous node */
public void setLinkPrev(Node p) {
prev = p;
}
/* Funtion to get link to next node */
public Node getNext() {
return next;
}
/* Function to get link to previous node */
public Node getPrev() {
return prev;
}
/* Function to set information to node */
public void setInformazione(int i) {
informazione = i;
}
/* Function to get data from node */
public int getInformazione() {
return informazione;
}
/* Function to set data to node */
public void setData(int d) {
data = d;
}
/* Function to get data from node */
public int getData() {
return data;
}
}`
in this code you can only enter INT values for both of the node slots, the second slot is fine, must be an int, meanwhile the first slot have to be an String.
Thank all for help.
You should make your Node class generic, and let it accept any class as data.
class Node<T> {
T data;
Node<T> prev;
Node<T> next;
public Node (T data, Node<T> prev, Node<T> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
Now you can define a class (let's call it SomeClass) that contains all the properties you want to store in a given Node, and create a Node with:
Node<SomeClass> n = new Node<SomeClass>(new SomeClass(information,key), null, null);
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()));
}
Here is the part of code of the binary tree class that I'm writing.
class Node<T> {
private T value;
private Node<T> left;
private Node<T> right;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public Node() {}
public Node(T value) {
this.value = value;
}
public Node(T value, Node<T> left, Node<T> right) {
this.value = value;
this.left = left;
this.right = right;
}
}
import java.util.*;
public class Tree<T extends Comparable<T>> {
private Node<T> root;
private List<T> levelOrderList = new ArrayList<T>();
public Node<T> getRoot() {
return root;
}
public Tree() {
}
public Tree(Node<T> root) {
this.root = root;
}
private List<T> getLevelOrderList(Node<T> root){
if (root == null)
return Collections.emptyList();
Queue<Node<T>> level = new LinkedList<Node<T>>();
level.add(root);
while(!level.isEmpty()){
Node<T> node = level.poll();
levelOrderList.add(node.getValue());
if(node.getLeft() != null)
level.add(node.getLeft());
if(node.getRight() != null)
level.add(node.getRight());
}
return levelOrderList;
}
public List<T> getLevelOrderList() {
return getLevelOrderList(root);
}
}
The method getLevelOrderList() returns list of elements in tree in level by level order.
The question is: how to rewrite method getLevelOrderList using recursion?
What you need to do is remove the loop, and just focus on a single pass through what now is in the loop. You'll need to move some of that code out of the private method and into the public method you created. Like the check for root == null, level instantiation, etc. Then you'll just keep calling the private method until level is empty. Here is how I'd change the signature:
public List<T> getLevelOrderList() {
if( root == null ) return Collections.emptyCollection();
List<Node<T>> level = new ArrayList<Node<T>>();
List<T> values = new ArrayList<T>();
level.add( root );
return getLevelOrderList( level, values );
}
private List<T> getLevelOrderList(List<Node<T>> level, List<T> values) {
if( level.isEmpty() ) return values;
// do the next step to visit the node at the head of the list and recurse
}
That should be enough to get you started, but I can't give this away since it's clearly homework. Oh and your program had a bug if you called getLevelOrderList() twice it would never clear out the instance variable you had so it would return double the number of items from the tree. By not using instance variables I removed that bug.