I have got a binary tree
public class Node
{
int value;
Node left;
Node right;
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public String getValue() {
return value;
}
}
And in main I have got a function to traverse it.
For tree
5
/ \
3 7
/ \
1 2
First one creates a queue of nodes with breadth first traversal(5,3,7,1,2).
Second one returns value of a node for eg. 7 for number 2 or 2 for number 4.
private void queueOfTreaversed() {
LinkedList<Node> queue = new LinkedList<Node>();
if (root != null)
queue.add(root);
while (!queue.isEmpty()) {
Node temp = queue.removeFirst();
if (temp.getLeft() != null && temp.getRight() != null) {
traversed.add(temp); //there is a difference
queue.add(temp.getLeft());
queue.add(temp.getRight());
}
}
}
public int getValue(int n) {
LinkedList<Node> queue = new LinkedList<Node>();
if (root != null)
queue.add(root);
while (!queue.isEmpty() && n>0) {
Node temp = queue.removeFirst();
if (temp.getLeft() != null && temp.getRight() != null) {
queue.add(temp.getLeft());
queue.add(temp.getRight());
}
}
return queue.peekFirst().getValue(); //there is a difference
}
And I have got duplication of code that I do not how to get rid off.
I use traversed in meantime and pop elements from this queue so elements will not be in this order and traversed cannot be used. Could anyone give any hint?
Once you have got the traversed nodes in traversed, your getValue(int n) function can actually index into traversed to get the value you want. In your getValue(int n) function, just use code like this:
if (n < traversed.size()) {
return traversed.get(n).getValue();
}
throw new Exception("Element not existed");
To be able to use traversed, just return it in your queueOfTreaversed function.
Related
I am struggling with pushing values from a Binary Search Tree into an array, but I also need them to be sorted. Here are the instructions of what is needed.
The toArray method should create and return an array containing every element in the tree in sorted order ("in order"). The capacity of this array should equal the number of elements it contains. This method should make use of the recursive private helper method toArray(BSTNode, List) to generate the array. This array will need be created as an array of Comparable objects and cast to an array of E objects. You can use Collection's toArray(E[]) method to help with the array generation.
Therefore here is my code I have so far:
public E[] toArray()
{
List<E> lista = new ArrayList<E>();
toArray(root, lista);
E[] good = (E[]) lista.toArray();
return good;
}
private void toArray(BSTNode<E> node, List<E> aList)
{
if(node.left != null)
{
aList.add(node.left.data);
}
}
Here is the rest of the code for references, but I am more focused on the toArray methods more than anything. I can't figure out how to sort them into an array. Please help.
public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;
// post: constructs an empty search tree
public BinarySearchTree()
{
root = null;
}
// post: value added to tree so as to preserve binary search tree
public void add(E value)
{
root = add(root, value);
}
// post: value added to tree so as to preserve binary search tree
private BSTNode<E> add(BSTNode<E> node, E value)
{
if (node == null)
{
node = new BSTNode<E>(value);
numElements++;
}
else if (node.data.compareTo(value) > 0)
{
node.left = add(node.left, value);
}
else if (node.data.compareTo(value) < 0)
{
node.right = add(node.right, value);
}
return node;
}
// post: returns true if tree contains value, returns false otherwise
public boolean contains(E value)
{
return contains(root, value);
}
// post: returns true if given tree contains value, returns false otherwise
private boolean contains(BSTNode<E> node, E value)
{
if (node == null)
{
return false;
}
else
{
int compare = value.compareTo(node.data);
if (compare == 0)
{
return true;
}
else if (compare < 0)
{
return contains(node.left, value);
}
else
{ // compare > 0
return contains(node.right, value);
}
}
}
public void remove(E value)
{
root = remove(root, value);
}
private BSTNode<E> remove(BSTNode<E> node, E value)
{
if(node == null)
{
return null;
}
else if(node.data.compareTo(value) < 0)
{
node.right = remove(node.right, value);
}
else if(node.data.compareTo(value) > 0)
{
node.left = remove(node.left, value);
}
else
{
if(node.right == null)
{
numElements--;
return node.left;// no R child; replace w/ L
}
else if(node.left == null)
{
numElements--;
return node.right; // no L child; replace w/ R
}
else
{
// both children; replace w/ max from L
node.data = getMax(node.left);
node.left = remove(node.left, node.data);
}
}
return node;
}
private E getMax(BSTNode<E> node)
{
if(node.right == null)
{
return node.data;
}
else
{
return getMax(node.right);
}
}
public void clear()
{
root = null;
numElements--;
}
public boolean isEmpty()
{
if(numElements == 0)
{
return true;
}
else
{
return false;
}
}
public int size()
{
return numElements;
}
//My toArray Methods will go here.
public Iterator<E> iterator()
{
return new Iterator<>(root);
}
public static class Iterator<E>
{
private Stack<BSTNode<E>> stack;
public Iterator(BSTNode<E> node)
{
this.stack = new Stack<>();
while (node != null)
{
stack.push(node);
node = node.left;
}
}
public boolean hasNext()
{
return !stack.isEmpty();
}
public E next()
{
BSTNode<E> goodDays = stack.pop();
E result = goodDays.data;
if (goodDays.right != null)
{
goodDays = goodDays.right;
while (goodDays != null)
{
stack.push(goodDays);
goodDays = goodDays.left;
}
}
return result;
}
}
private static class BSTNode<E>
{
public E data;
public BSTNode<E> left;
public BSTNode<E> right;
public BSTNode(E data)
{
this(data, null, null);
}
public BSTNode(E data, BSTNode<E> left, BSTNode<E> right)
{
this.data = data;
this.left = left;
this.right = right;
}
}
}
Wait, this is a Binary Search Tree so it's already sorted.
Then you need to walk the tree.
Given you have something like:
4
/ \
2 6
\ / \
3 5 9
To insert it you have to:
Given a tree root
A. If the tree is null, there's nothing to insert.
B. If is not null:
B.1 Insert everything on the left
B.2 Insert the tree root
B.3 Insert everything on the right
Which would look like this:
void walkAndInsert(tree, array) {
if (tree == null) {//A
return
} else { //B
walkAndInsert(tree.left) //B.1
array.add(tree.root) //B.2
walkAndInsert(tree.right) //B.3
}
}
So applying these steps on the array:
Is tree null? No, then execute step #B (insert all left, root and all right)
//B
tree =
4
/ \
2 6
\ / \
3 5 9
array =[]
We take the left branch and repeat the process (step #B.1, insert all the left):
Is tree null? No, then execute #B
//B.1
tree =
2
\
3
array =[]
Since the left branch is null, the next execution would like like this:
Is tree null ? yes, then return
//A
tree =
array = []
This will conclude step B.1, we can go now to step B.2, insert root
//B.2
tree =
2
\
3
array =[2]
Followed by step B.3 insert all from right
Is tree null? No (there's a 3 there),
//B.3
tree =
3
array =[2]
Then execute #B.1 on this tree
Is the tree empty? Yes, this concludes this B.1
//A
tree =
array =[2]
Now in B.2 we insert this root
Is tree null? No (there's a 3 there),
//B.2
tree =
3
array =[2,3]
And finally we go to B.3 insert all from right
But there's nothing there, so we just return
//A
tree =
array =[2,3]
This finishes the left branch from our very initial tree.
So after B.1 is finished on our initial tree, we execute B.2 and our data looks like:
// B.2 on the initial tree
tree =
4
/ \
2 6
\ / \
3 5 9
array =[2,3,4]
And we repeat with the right side
Is null? no, then B on the branch with 5, insert 6, and step B on the branch with 9
//B.3
tree =
6
/ \
5 9
array =[2,3,4]
// B.1
tree =
5
array =[2,3,4]
// A
tree =
array =[2,3,4]
// B.2
tree =
5
array =[2,3,4,5]
// B.2
tree =
6
/ \
5 9
array =[2,3,4,5,6]
// B.3
tree =
9
array =[2,3,4,5,6]
// A
tree =
array =[2,3,4,5,6]
// B.2
tree =
9
array =[2,3,4,5,6,9]
Working example of the steps described here
import java.util.*;
import java.lang.reflect.Array;
import static java.lang.System.out;
class Tree<E extends Comparable<E>> {
E root;
Tree<E> left;
Tree<E> right;
void insert(E element) {
if (this.root == null) {
this.root = element;
this.left = new Tree<E>();
this.right = new Tree<E>();
} else if (element.compareTo(this.root) < 0 ) {
left.insert(element);
} else {
right.insert(element);
}
}
E[] toArray() {
List<E> a = new ArrayList<>();
toArray(this, a);
#SuppressWarnings("unchecked")
final E[] r = a.toArray((E[]) Array.newInstance(a.get(0).getClass(), a.size()));
return r;
}
// instance method just to retain the generic type E
private void toArray(Tree<E> t, List<E> list) {
if (t == null || t.root == null) {
return;
} else {
toArray(t.left, list);
list.add(t.root);
toArray(t.right, list);
}
}
public static void main(String ... args) {
Tree<String> t = new Tree<>();
t.insert("hola");
t.insert("adios");
t.insert("fuimonos");
System.out.println(Arrays.toString(t.toArray()));
}
}
I figured it out. I will disclose the code and explain what's going on.
In the public I make a List that will soon be an Array List.
Then I call the toArray helper method (private) to set the values. Root for the top one and lista for the list it will go in.
After make the Array and set the size with numElements. Comparable is in there since at the very top of my code, that's what it extends.
Then put the that array into the lista.
Finally return it.
public E[] toArray()
{
List<E> lista = new ArrayList<E>();
toArray(root, lista);
E[] arr = (E[]) new Comparable[numElements];
lista.toArray(arr);
return arr;
}
In the private I do some recursion.
As long as the node is not empty(null) then the array will search for left nodes continuously until it has no left (left) therefore add that into the array.
Then adds the right ones.
private void toArray(BSTNode<E> node, List<E> aList)
{
if(node != null)
{
toArray(node.left, aList);
aList.add(node.data);
toArray(node.right, aList);
}
}
Sorry if that was hard to understand, I'm not the best at explaining things, however this worked for me.
I am struggling to figure out how to code a recursive algorithm to count the number of leaves in a Binary Tree (not a complete tree). I get as far as traversing to the far most left leaf and don't know what to return from there. I am trying to get the count by loading the leaves into a list and getting the size of that list. This is probably a bad way to go about the count.
public int countLeaves ( ) {
List< Node<E> > leafList = new ArrayList< Node<E> >();
//BinaryTree<Node<E>> treeList = new BinaryTree(root);
if(root.left != null)
{
root = root.left;
countLeaves();
}
if(root.right != null)
{
root = root.right;
countLeaves();
}
if(root.left == null && root.right == null)
{
leafList.add(root);
}
return();
}
Elaborating on #dasblinkenlight idea. You want to recursively call a countleaves on root node & pass back the # to caller. Something on the following lines.
public int countLeaves() {
return countLeaves(root);
}
/**
* Recursively count all nodes
*/
private static int countLeaves (Node<E> node) {
if(node==null)
return 0;
if(node.left ==null && node.right == null)
return 1;
else {
return countLeaves(node.left) + countLeaves(node.right);
}
}
Edit: It appears, a similar problem was previously asked counting number of leaf nodes in binary tree
The problem with your implementation is that it does not restore the value of member variable root back to the state that it had prior to entering the method. You could do it by storing the value in a local variable, i.e.
Node<E> oldRoot = root;
... // your method goes here
root = oldRoot;
However, a better approach is to take Node<E> as an argument, rather than relying on a shared variable:
public int countLeaves() {
return countLeaves(root);
}
private static int countLeaves (Node<E> node) {
... // Do counting here
}
I have written a code to insert an element in a binary tree in java. Here are the functions to do the same:
public void insert(int data)
{
root = insert(root, data);
}
private Node insert(Node node, int data)
{
if (node == null)
node = new Node(data);
else
{
if (node.getRight() == null)
node.right = insert(node.right, data);
else
node.left = insert(node.left, data);
}
return node;
}
However when I traverse the tree, the answer I get is wrong. Here are the traversal functions (preorder):
public void preorder()
{
preorder(root);
}
private void preorder(Node r)
{
if (r != null)
{
System.out.print(r.getData() +" ");
preorder(r.getLeft());
preorder(r.getRight());
}
}
Okay so as suggested here's the definition for the Node class:
public class Node {
public int data;
public Node left, right;
/* Constructor */
public Node() {
left = null;
right = null;
data = 0;
}
/* Constructor */
public Node(int d, Node l, Node r) {
data = d;
left = l;
right = r;
}
//Constructor
public Node(int d) {
data = d;
}
/* Function to set link to next Node */
public void setLeft(Node l) {
left = l;
}
/* Function to set link to previous Node */
public void setRight(Node r) {
right = r;
}
/* Function to set data to current Node */
public void setData(int d) {
data = d;
}
/* Function to get link to next node */
public Node getLeft() {
return left;
}
/* Function to get link to previous node */
public Node getRight() {
return right;
}
/* Function to get data from current Node */
public int getData() {
return data;
}
}
I have re-checked the algorithm for traversal many times, and it's working perfectly. I believe the problem is in the insertion algorithm. Any suggestions?
If I understood correctly, you want to fill your binary tree in "layers". E.g. you want to put something into depth 4 only if depth 3 is "full binary tree".
Then the problem is whole logic of your insert algorithm that is DFS-based. In other words it inserts elements deeper and deeper on the one side instead of building full binary tree on both sides.
If you look closer to your insert algorithm you will see that once you skip "right" subtree, you will never return to it - even if the "left" subtree is already full binary tree. That leads to the tree that will be growing deeper and deeper on the left side but not growing on the right side.
Speaking in programming language. You do:
(node.right != null) && (node.left != null) => insert (node.left)
but you can't do this (start inserting node.left). What if node.left has both children and node.right has no children? You will attempt to insert to the left even you should do it in node.right.
So what you really need to do insertion BFS-based. That means you will traverse the tree for insertion "in layers". Queue should be your new friend here:-) (not the stack/recursion):
public void insert(int data) {
if (root == null) {
root = new Node(data);
return;
}
Queue<Node> nodesToProcess = new LinkedList<>();
nodesToProcess.add(root);
while (true) {
Node actualNode = nodesToProcess.poll();
// Left child has precedence over right one
if (actualNode.left == null) {
actualNode.left = new Node(data);
return;
}
if (actualNode.right == null) {
actualNode.right = new Node(data);
return;
}
// I have both children set, I will process them later if needed
nodesToProcess.add(actualNode.left);
nodesToProcess.add(actualNode.right);
}
}
Your method returns given node, but your method has to return inserted node which is node.right or node.left
I have a ordered binary tree:
4
|
|-------|
2 5
|
|-------|
1 3
The leaves point to null. I have to create a doubly link list which should look like
1<->2<->3<->4<->5
(Obviously 5 should point to 1)
The node class is as follows:
class Node {
Node left;
Node right;
int value;
public Node(int value)
{
this.value = value;
left = null;
right = null;
}
}
As you can see the doubly link list is ordered (sorted) as well.
Question: I have to create the linked list form the tree without using any extra pointers. The left pointer of the tree should be the previous pointer of the list and the right pointer of the tree should be the next pointer of the list.
What I thought off: Since the tree is an ordered tree, the inorder traversal would give me a sorted list. But while doing the inorder traversal I am not able to see, where and how to move the pointers to form a doubly linked list.
P.S I checked some variations of this question but none of them gave me any clues.
It sounds like you need a method that accepts a Node reference to the root of the tree and returns a Node reference to the head of a circular list, where no new Node objects are created. I would approach this recursively, starting with the simple tree:
2
|
|-----|
1 3
You don't say whether the tree is guaranteed to be full, so we need to allow for 1 and/or 3 being null. The following method should work for this simple tree:
Node simpleTreeToList(Node root) {
if (root == null) {
return null;
}
Node left = root.left;
Node right = root.right;
Node head;
if (left == null) {
head = root;
} else {
head = left;
left.right = root;
// root.left is already correct
}
if (right == null) {
head.left = root;
root.right = head;
} else {
head.left = right;
right.right = head;
right.left = root;
}
return head;
}
Once it is clear how this works, it isn't too hard to generalize it to a recursive method that works for any tree. It is a very similar method:
Node treeToList(Node root) {
if (root == null) {
return null;
}
Node leftTree = treeToList(root.left);
Node rightTree = treeToList(root.right);
Node head;
if (leftTree == null) {
head = root;
} else {
head = leftTree;
leftTree.left.right = root;
root.left = leftTree.left;
}
if (rightTree == null) {
head.left = root;
root.right = head;
} else {
head.left = rightTree.left;
rightTree.left.right = head;
rightTree.left = root;
root.right = rightTree;
}
return head;
}
If I got all the link assignments covered correctly, this should be all you need.
Do an in-order traversal of the list, adding each list item to the doubly linked list as you encounter it. When done, add an explicit link between the first and last items.
Update 3/6/2012: Since you must reuse the Node objects you already have, after you put the node objects into the the list, you can then iterate over the list and reset the left and right pointers of the Node objects to point to their siblings. Once that is done, you can get rid of the list and simply return the first node object.
This should also work:
NodeLL first = null;
NodeLL last = null;
private void convertToLL(NodeBST root) {
if (root == null) {
return;
}
NodeLL newNode = new NodeLL(root.data);
convertToLL(root.left);
final NodeLL l = last;
last = newNode;
if (l == null)
first = newNode;
else {
l.next = newNode;
last.prev = l;
}
convertToLL(root.right);
}
Let your recursion return the left and right end of formed list. Then you link your current node to the last of the left list, and first of the right list. Basic case it, when there is no left or right element, which is the node it self for both. Once all is done, you can link the first and last of the final result. Below is the java code.
static void convertToSortedList(TreeNode T){
TreeNode[] r = convertToSortedListHelper(T);
r[1].next = r[0];
r[0].prev= r[1];
}
static TreeNode[] convertToSortedListHelper(TreeNode T){
TreeNode[] ret = new TreeNode[2];
if (T == null) return ret;
if (T.left == null && T.right == null){
ret[0] = T;
ret[1] = T;
return ret;
}
TreeNode[] left = TreeNode.convertToSortedListHelper(T.left);
TreeNode[] right = TreeNode.convertToSortedListHelper(T.right);
if (left[1] != null) left[1].next = T;
T.prev = left[1];
T.next = right[0];
if (right[0] != null) right[0].prev = T;
ret[0] = left[0]==null? T:left[0];
ret[1] = right[1]==null? T:right[1];
return ret;
}
Add the following method to your Node class
public Node toLinked() {
Node leftmost = this, rightmost = this;
if (right != null) {
right = right.toLinked();
rightmost = right.left;
right.left = this;
}
if (left != null) {
leftmost = left.toLinked();
left = leftmost.left;
left.right = this;
}
leftmost.left = rightmost;
rightmost.right = leftmost;
return leftmost;
}
EDIT By maintaining the invariant that the list returned by toLinked() has the proper form, you can easily get the left- and rightmost nodes in the sublist returned by the recursive call on the subtrees
/* input: root of BST. Output: first node of a doubly linked sorted circular list. **Constraints**: do it in-place. */
public static Node transform(Node root){
if(root == null){
return null;
}
if(root.isLeaf()){
root.setRight(root);
root.setLeft(root);
return root;
}
Node firstLeft = transform(root.getLeft());
Node firstRight = transform(root.getRight());
Node lastLeft = firstLeft == null ? null : firstLeft.getLeft();
Node lastRight= firstRight == null ? null : firstRight.getLeft();
if(firstLeft != null){
lastLeft.setRight(root);
root.setLeft(lastLeft);
if(lastRight == null){
firstLeft.setLeft(root);
}
else{
firstLeft.setLeft(lastRight);
root.setRight(firstRight);
}
}
if(firstRight != null){
root.setRight(firstRight);
firstRight.setLeft(root);
if(lastLeft == null){
root.setLeft(lastRight);
lastRight.setLeft(root);
firstLeft = root;
}
else{
root.setLeft(lastLeft);
lastRight.setRight(firstLeft);
}
}
return firstLeft;
}
I want to remove duplicates from sorted linked list {0 1 2 2 3 3 4 5}.
`
public Node removeDuplicates(Node header)
{
Node tempHeader = null;
if(header != null)
tempHeader = header.next;
else return header;
Node prev = header;
if((tempHeader == null)) return header ;
while(tempHeader != null)
{
if(tempHeader.data != prev.data)
{
prev.setNext(tempHeader);
}
tempHeader = tempHeader.next;
}
prev = header;
printList(prev);
return tempHeader;
}
`
prev.setNext(tempHeader) is not working correctly inside the while loop. Ideally when prev = 2 and tempHeader = 3, prev.next should be node with data = 3.
Printlist function just takes header pointer and prints the list.
Node definition is given below.
public class Node
{
int data;
Node next;
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
The loop is sorted, so you know that duplicates are going to sit next to each other. If you want to edit the list in place then, you've got to have two list pointers (which you do). The one you call tempHeader and prev, and you've got to advance them both in the the list as you go (which I don't see in the code). Otherwise, if you don't advance the prev pointer as you go, then you're always comparing the element under tempHeader to the first item in the list, which is not correct.
An easier way to do this, however, is to build a new list as you go. Simply remember the value of the last item that you appended to the list. Then if the one that you're about to insert is the same then simply don't insert it, and when you're done, just return your new list.
I can give you 2 suggestions for the above suggestion
1) Convert the linked List to Set, that will eliminate the duplicates and
Back from Set to the Linked list
Code to get this done would be
linkedList = new LinkedList<anything>(new HashSet<anything>(origList));
2) You can use LinkedHashSet, if you dont want any duplicates
In this case no return value is needed.
public void removeDuplicates(Node list) {
while (list != null) {
// Walk to next unequal node:
Node current = list.next;
while (current != null && current.data.equals(list.data)) {
current = current.next;
}
// Skip the equal nodes:
list.next = current;
// Take the next unequal node:
list = current;
}
}
public ListNode removeDuplicateElements(ListNode head) {
if (head == null || head.next == null) {
return null;
}
if (head.data.equals(head.next.data)) {
ListNode next_next = head.next.next;
head.next = null;
head.next = next_next;
removeDuplicateElements(head);
} else {
removeDuplicateElements(head.next);
}
return head;
}
By DoublyLinked List and using HashSet,
public static void deleteDups(Node n) {
HashSet<Integer> set = new HashSet<Integer>();
Node previous = null;
while (n != null) {
if (set.contains(n.data)) {
previous.next = n.next;
} else {
set.add(n.data);
previous = n;
}
n = n.next;
}
}
doublylinkedList
class Node{
public Node next;
public Node prev;
public Node last;
public int data;
public Node (int d, Node n, Node p) {
data = d;
setNext(n);
setPrevious(p);
}
public Node() { }
public void setNext(Node n) {
next = n;
if (this == last) {
last = n;
}
if (n != null && n.prev != this) {
n.setPrevious(this);
}
}
public void setPrevious(Node p) {
prev = p;
if (p != null && p.next != this) {
p.setNext(this);
}
}}