Binary-Search Tree - java

Here is my code to find position of a certain element. And I am using Binary tree to store my Dictionary I want to know why it shows warning for Comparable-type. I have to use this in my project where element is a string type.
public int get(Comparable element){
return getPosition(element,root);
}
private int getPosition(Comparable element, TreeNode root){
int count = 0;
if (root == null){
return -1;
}else{
Stack t = new Stack();
t.push(root);
while(!t.empty()){
TreeNode n = (TreeNode)t.pop();
if(element.compareTo(n.value)==0){
return count;
}else{
if(n.getLeftTree()!=null){
t.push(n.getLeftTree());
count++;
}
if (n.getRightTree()!= null){
t.push(n.getRightTree());
count++;
}
}
}
return -1;
}
}

The java generic typing parameters are missing <...>.
public int get(Comparable<?> element){
return getPosition(element, root);
}
private int getPosition(Comparable<?> element, TreeNode root) {
int count = 0;
if (root == null) {
return -1;
} else {
Stack<TreeNde> t = new Stack<>();
t.push(root);
while (!t.empty()) {
TreeNode n = t.pop();
if (element.compareTo(n.value) == 0) {
return count;
} else {
if (n.getLeftTree() != null) {
t.push(n.getLeftTree());
count++;
}
if (n.getRightTree() != null) {
t.push(n.getRightTree());
count++;
}
}
}
}
return -1;
}
However the algorithm seems not to be counting the leftish part of the tree upto the found element. However if position is not the index in the sorted elements, that might be okay. (I did not check the correctness, as there is no early < check.) If this was a home work assignment, "non-recursive with stack," rework a recursive version. Probably two nested loops, and a comparison on -1 and +1.

Related

Summing elements of binary tree in Java

I'm trying to sum the elements of a binary tree with a recursive and an iterative method. While the recursive one works finde, the iterative gives me an exception.
import java.util.Queue;
public class BinTree {
public BinNode root;
public boolean insertNode(BinNode bn) {
BinNode child=null, parent=null;
// Knoten suchen, nach welchem eingefuegt wird
child = root;
while( child != null) {
parent = child;
if (bn.element == child.element) return false;
else if (bn.element < child.element) child = child.left;
else child = child.right;
}
// Baum leer?
if (parent==null) root = bn;
// Einfuegen nach parent, links
else if (bn.element < parent.element) parent.left = bn;
// Einfuegen nach parent, rechts
else parent.right = bn;
return true;
}
public BinNode findNode(int value) {
BinNode n = root;
while (n != null) {
if (value == n.element) { return n; }
else if (value < n.element) { n = n.left; }
else { n = n.right; }
}
return null;
}
public String toString() {
return root.toString();
}
//Max des Gesamtbaumes
public int max(){
if(root==null){
return 0;
}
else {
return root.max();
}
}
//(Iterativ)
public int max2(){
//The line that throws out the exception
Queue q = new LinkedList();
int sum = 0;
if(root!=null){
q.add(root);
}
while(!q.isEmpty()){
BinNode node = (BinNode) q.remove();
if(node.left == null && node.right == null){
sum = sum + node.element;
}
else{
if(node.left != null){
q.add(node.left);
}
}
if(node.right != null){
q.add(node.right);
}
}
return sum;
}
}
The Queue q = new LinkedList(); in the max2-Method is giving me the Exception:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types: javaapplication34.LinkedList cannot be converted to java.util.Queue
Could anyone help here? Give me a kickstart or a little explanation? I'm very unsure what's the issue in detail.
I didn't add every class here, since most of them are common. But if needed I'll add them.
It appears that you have defined a class called LinkedList in the same package, and it doesn't implement Queue.
If you want to use a java.util.LinkedList, you should either import or use the entire qualified name.
We don't know the implementation of you special LinkedList class (only that it does not implement the java.lang.Queue interface), but it may work already if you just say:
LinkedList q = new LinkedList();
(I assume that it is an assignment and that you have to use this special LinkedList for the task)

How do I write my method for balancing my BST?

So I have written an implementation of a BST in Java. My goal is to make it balanced aswell, more precisly an AVL tree. I am having some problem though, I don't know how to implement the trinodeRestructering method(ie the method that balances the tree) I have tried various things but these pointers are sometimes difficult to deal with and I am not sure how to do this recursivly. Down below is my code for adding a new element and the method to check if we are more than 2 steps difference in the tree.
add and balancing method:
private TreeNode insert(TreeNode currN, TreeNode newN) {
if (currN == null) {
return newN;
}
if (currN.getData() == newN.getData()) {
throw new IllegalArgumentException("Value already exists.");
}
if (newN.getData() < currN.getData()) {
if (currN.getLeft() == null) {
currN.setLeft(newN);
} else {
insert(currN.getLeft(), newN);
}
} else {
if (currN.getRight() == null) {
currN.setRight(newN);
} else {
insert(currN.getRight(), newN);
}
}
if (needBalancing()) {
trinodeRestructering(currN);
}
return currN;
}
private TreeNode trinodeRestructering(TreeNode currN) {
//Not sure what to do here.
return currN;
}
height checking method.
public boolean needBalancing(){
if(height(root) == -1){ // true if we need to balance
return true;
}else{
return false;
}
}
private int height(TreeNode node){
if (node == null)
return 0;
int left = height(node.getLeft());
int right = height(node.getRight());
if (left == -1 || right == -1)
return -1;
if (Math.abs(left - right) > 1) {
return -1;
}
return Math.max(left, right) + 1;
}
I might add that I got an working inOrder method, perhaps I could use it to balance my tree?

Finding a node in a binary search tree in java?

I am trying to write a method that returns the depth of a target int in a binary search tree. Right now it works for some smaller trees, but not always. Does anyone see where I may be going wrong?
static int count=1;
public static int findDepth(TreeNode<Integer> root, int target)
// pre: 0 or more elements in the tree, integer to search for
// post: return depth of target if found, -1 otherwise
{
count++;
if (root!=null)
{
if (root.getValue()<target)
{
if (root.getValue()==target)
{System.out.println(count);
return count;}
else
{findDepth(root.getLeft(), target);
count--;
findDepth(root.getRight(), target);
}
}
else if (root.getValue()>target)
{
if (root.getValue()==target)
{System.out.println(count);
return count;}
else
{findDepth(root.getLeft(), target);
count--;
findDepth(root.getRight(), target);
}
}
else if (root.getValue()==target)
return 1;
else
return -1;
}
return count;
}
There's a few things wrong.
It will never get into this case:
if (root.getValue()<target)
{
if (root.getValue()==target)
{System.out.println(count);
return count;}
Also it will never get into this case:
else if (root.getValue()>target)
{
if (root.getValue()==target)
{System.out.println(count);
return count;}
The biggest issue is that you're keeping a global static count, and recursively going through both left and right paths.
First of all, for a BST, there is no need to go both left and right.
Second, it's better to pass the count through a parameter rather than keeping a global.
Rather than fix your code, I'll post this working example for you to use as a reference:
public class Main
{
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.add(20);
tree.add(10);
tree.add(30);
tree.add(15);
tree.add(25);
tree.add(5);
tree.add(35);
tree.add(1);
tree.add(6);
tree.add(14);
tree.add(16);
tree.add(24);
tree.add(26);
tree.add(34);
tree.add(36);
int level = tree.getLevel(6);
System.out.println(level);
}
}
public class TreeNode
{
int data;
TreeNode left;
TreeNode right;
public TreeNode(int d){
data = d;
left = null;
right = null;
}
}
public class BinaryTree
{
TreeNode root;
public BinaryTree(){
root = null;
}
public int getLevel(int val) {
if (root == null) return 0;
return getLevelHelper(root, val, 0);
}
public int getLevelHelper(TreeNode node, int val, int level){
int retVal = -1;
if (node.data == val){
return level;
}
if (val < node.data && node.left != null){
retVal = getLevelHelper(node.left, val, level + 1);
}
else if (val > node.data && node.right != null){
retVal = getLevelHelper(node.right, val, level + 1);
}
return retVal;
}
public boolean add(int newData){
if (root == null){
root = new TreeNode(newData);
return true;
}
else{
TreeNode curr = root;
while (true){
if (curr.data == newData){
return false;
}
else if (curr.data > newData){
if (curr.left == null){
curr.left = new TreeNode(newData);
return true;
}
else{
curr = curr.left;
}
}
else{
if (curr.right == null){
curr.right = new TreeNode(newData);
return true;
}
else{
curr = curr.right;
}
}
}
}
}
}

Recursively find nth to last element in linked list

I'm practicing basic data structure stuff and I'm having some difficulties with recursion. I understand how to do this through iteration but all of my attempts to return the nth node from the last of a linked list via recursion result in null. This is my code so far:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
findnthToLastRecursion(node.next(), pos);
if(++i == pos) return node;
return null;
}
Can anyone help me understand where I'm going wrong here?
This is my iterative solution which works fine, but I'd really like to know how to translate this into recursion:
public static Link.Node findnthToLast(Link.Node head, int n) {
if (n < 1 || head == null) {
return null;
}
Link.Node pntr1 = head, pntr2 = head;
for (int i = 0; i < n - 1; i++) {
if (pntr2 == null) {
return null;
} else {
pntr2 = pntr2.next();
}
}
while (pntr2.next() != null) {
pntr1 = pntr1.next();
pntr2 = pntr2.next();
}
return pntr1;
}
You need to go to the end and then count your way back, make sure to pass back the node each time its passed back. I like one return point
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
Link.Node result = node;
if(node != null) {
result = findnthToLastRecursion(node.next, pos);
if(i++ == pos){
result = node;
}
}
return result;
}
Working example outputs 7 as 2 away from the 9th and last node:
public class NodeTest {
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
/**
* #param args
*/
public static void main(String[] args) {
Node first = null;
Node prev = null;
for (int i = 0; i < 10; i++) {
Node current = new Node(prev, Integer.toString(i),null);
if(i==0){
first = current;
}
if(prev != null){
prev.next = current;
}
prev = current;
}
System.out.println( findnthToLastRecursion(first,2).item);
}
public static int i = 0;
public static Node findnthToLastRecursion(Node node, int pos) {
Node result = node;
if (node != null) {
result = findnthToLastRecursion(node.next, pos);
if (i++ == pos) {
result = node;
}
}
return result;
}
}
No need for static variables.
public class List {
private Node head = null;
// [...] Other methods
public Node findNthLastRecursive(int nth) {
if (nth <= 0) return null;
return this.findNthLastRecursive(this.head, nth, new int[] {0});
}
private Node findNthLastRecursive(Node p, int nth, int[] pos) {
if (p == null) {
return null;
}
Node n = findNthLastRecursive(p.next, nth, pos);
pos[0]++;
if (pos[0] == nth) {
n = p;
}
return n;
}
}
You can do this a couple of ways:
recurse through the list once to find the list length, then write a recursive method to return the kth element (a much easier problem).
use an auxiliary structure to hold the result plus the remaining length; this essentially replaces the two recursions of the first option with a single recursion:
static class State {
Link.Node result;
int trailingLength;
}
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
State state = new State();
findnthToLastRecursion(node, pos, state);
return state.result;
}
private static void findnthToLastRecursion(Link.Node node, int pos, State state) {
if (node == null) {
state.trailingLength = 0;
} else {
findnthToLastRecursion(node.next(), state);
if (pos == state.trailingLength) {
state.result = node;
}
++state.trailingLength;
}
}
I misunderstood the question. Here is an answer based on your iterative solution:
public static Link.Node findnthToLast(Link.Node head, int n) {
return findnthToLastHelper(head, head, n);
}
private static Link.Node findnthToLastHelper(Link.Node head, Link.Node end, int n) {
if ( end == null ) {
return ( n > 0 ? null : head);
} elseif ( n > 0 ) {
return findnthToLastHelper(head, end.next(), n-1);
} else {
return findnthToLastHelper(head.next(), end.next(), 0);
}
}
actually you don't need to have public static int i = 0; . for utill method the pos is :
pos = linked list length - pos from last + 1
public static Node findnthToLastRecursion(Node node, int pos) {
if(node ==null){ //if null then return null
return null;
}
int length = length(node);//find the length of the liked list
if(length < pos){
return null;
}
else{
return utill(node, length - pos + 1);
}
}
private static int length(Node n){//method which finds the length of the linked list
if(n==null){
return 0;
}
int count = 0;
while(n!=null){
count++;
n=n.next;
}
return count;
}
private static Node utill(Node node, int pos) {
if(node == null) {
return null;
}
if(pos ==1){
return node;
}
else{
return utill(node.next, pos-1);
}
}
Here node.next is the next node. I am directly accessing the next node rather than calling the next() method. Hope it helps.
This cheats (slightly) but it looks good.
public class Test {
List<String> list = new ArrayList<> (Arrays.asList("Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"));
public static String findNthToLastUsingRecursionCheatingALittle(List<String> list, int n) {
int s = list.size();
return s > n
// Go deeper!
? findNthToLastUsingRecursionCheatingALittle(list.subList(1, list.size()), n)
// Found it.
: s == n ? list.get(0)
// Too far.
: null;
}
public void test() {
System.out.println(findNthToLastUsingRecursionCheating(list,3));
}
public static void main(String args[]) {
new Test().test();
}
}
It prints:
Eight
which I suppose is correct.
I have use List instead of some LinkedList variant because I do not want to reinvent anything.
int nthNode(struct Node* head, int n)
{
if (head == NULL)
return 0;
else {
int i;
i = nthNode(head->left, n) + 1;
printf("=%d,%d,%d\n", head->data,i,n);
if (i == n)
printf("%d\n", head->data);
}
}
public class NthElementFromLast {
public static void main(String[] args) {
List<String> list = new LinkedList<>();
Stream.of("A","B","C","D","E").forEach(s -> list.add(s));
System.out.println(list);
System.out.println(getNthElementFromLast(list,2));
}
private static String getNthElementFromLast(List list, int positionFromLast) {
String current = (String) list.get(0);
int index = positionFromLast;
ListIterator<String> listIterator = list.listIterator();
while(positionFromLast>0 && listIterator.hasNext()){
positionFromLast--;
current = listIterator.next();
}
if(positionFromLast != 0) {
return null;
}
String nthFromLast = null;
ListIterator<String> stringListIterator = list.listIterator();
while(listIterator.hasNext()) {
current = listIterator.next();
nthFromLast = stringListIterator.next();
}
return nthFromLast;
}
}
This will find Nth element from last.
My approach is simple and straight,you can change the array size depending upon your requirement:
int pos_from_tail(node *k,int n)
{ static int count=0,a[100];
if(!k) return -1;
else
pos_from_tail(k->next,n);
a[count++]=k->data;
return a[n];
}
You'll have make slight changes in the code:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
**Link.Node temp = findnthToLastRecursion(node.next(), pos);
if(temp!=null)
return temp;**
if(++i == pos) return node;
return null;
}
}

Finding if a number is equal to sum of 2 nodes in a binary search tree

Here is my code that for this. I am traversing the whole tree and then doing a find on each node. find() takes O(log n), and so the whole program takes O(n log n) time.
Is there a better way to implement this program? I am not just talking of better in terms of time complexity but in general as well. How best to implement this?
public boolean searchNum(BinTreeNode node, int num) {
//validate the input
if (node == null) {
return false;
}
// terminal case for recursion
int result = num - node.item;
//I have a separate find() which finds if the key is in the tree
if (find(result)) {
return true;
}
return seachNum(node.leftChild, num) || searchNum(node.rightChilde, num);
}
public boolean find(int key) {
BinTreeNode node = findHelper(key, root);
if (node == null) {
return false;
} else {
return true;
}
}
private BinTreeNode findHelper(int key, BinTreeNode node) {
if (node == null) {
return null;
}
if (key == node.item) {
return node;
} else if (key < node.item) {
return findHelper(key, node.leftChild);
} else {
return findHelper(key, node.rightChild);
}
}
Finding two nodes in binary search tree sum to some value can be done in the similar way of finding two elements in a sorted array that sums to the value.
In the case with an array sorted from small to large, you keep two pointers, one start from beginning, one start from the end. If the sum of the two elements pointed by the pointers is larger than the target, you move the right pointer to left by one, if the sum is smaller than target, you move the left pointer to right by one. Eventually the two pointer will either points to two elements that sum to the target value, or meet in the middle.
boolean searchNumArray(int[] arr, int num) {
int left = 0;
int right = arr.length - 1;
while (left < right) {
int sum = arr[left] + arr[right];
if (sum == num) {
return true;
} else if (sum > num) {
right--;
} else {
left++;
}
}
return false;
}
If you do an in-order traversal of the binary search tree, it becomes a sorted array. So you can apply the same idea on binary search tree.
The following code do iterative in-order traversal from both directions. Stack is being used for the traversal, so the time complexity is O(n) and space complexity is O(h), where h is the height of the binary tree.
class BinTreeIterator implements Iterator<BinTreeNode> {
Stack<BinTreeNode> stack;
boolean leftToRight;
public boolean hasNext() {
return !stack.empty();
}
public BinTreeNode next() {
return stack.peek();
}
public void remove() {
BinTreeNode node = stack.pop();
if (leftToRight) {
node = node.rightChild;
while (node.rightChild != null) {
stack.push(node);
node = node.rightChild;
}
} else {
node = node.leftChild;
while (node.leftChild != null) {
stack.push(node);
node = node.leftChild;
}
}
}
public BinTreeIterator(BinTreeNode node, boolean leftToRight) {
stack = new Stack<BinTreeNode>();
this.leftChildToRight = leftToRight;
if (leftToRight) {
while (node != null) {
stack.push(node);
node = node.leftChild;
}
} else {
while (node != null) {
stack.push(node);
node = node.rightChild;
}
}
}
}
public static boolean searchNumBinTree(BinTreeNode node, int num) {
if (node == null)
return false;
BinTreeIterator leftIter = new BinTreeIterator(node, true);
BinTreeIterator rightIter = new BinTreeIterator(node, false);
while (leftIter.hasNext() && rightIter.hasNext()) {
BinTreeNode left = leftIter.next();
BinTreeNode right = rightIter.next();
int sum = left.item + right.item;
if (sum == num) {
return true;
} else if (sum > num) {
rightIter.remove();
if (!rightIter.hasNext() || rightIter.next() == left) {
return false;
}
} else {
leftIter.remove();
if (!leftIter.hasNext() || leftIter.next() == right) {
return false;
}
}
}
return false;
}
Chen Pang has already given a perfect answer. However, I was trying the same problem today and I could come up with the following solution. Posting it here as it might help some one.
The idea is same as that of earlier solution, just that I am doing it with two stacks - one following the inorder(stack1) and another following reverse - inorder order(stack2). Once we reach the left-most and the right-most node in a BST, we can start comparing them together.
If the sum is less than the required value, pop out from stack1, else pop from stack2. Following is java implementation of the same:
public int sum2(TreeNode A, int B) {
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
TreeNode cur1 = A;
TreeNode cur2 = A;
while (!stack1.isEmpty() || !stack2.isEmpty() ||
cur1 != null || cur2 != null) {
if (cur1 != null || cur2 != null) {
if (cur1 != null) {
stack1.push(cur1);
cur1 = cur1.left;
}
if (cur2 != null) {
stack2.push(cur2);
cur2 = cur2.right;
}
} else {
int val1 = stack1.peek().val;
int val2 = stack2.peek().val;
// need to break out of here
if (stack1.peek() == stack2.peek()) break;
if (val1 + val2 == B) return 1;
if (val1 + val2 < B) {
cur1 = stack1.pop();
cur1 = cur1.right;
} else {
cur2 = stack2.pop();
cur2 = cur2.left;
}
}
}
return 0;
}
As far as I know, O(log n) is the best possible searching function you can use. I'm interested in the "n". If you're using a for-loop somewhere, consider using a hashtable in its stead. Hash table seeking is O(1) if I recall correctly.
From http://www.geeksforgeeks.org/find-a-pair-with-given-sum-in-bst/
/* In a balanced binary search tree isPairPresent two element which sums to
a given value time O(n) space O(logn) */
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// A BST node
struct node
{
int val;
struct node *left, *right;
};
// Stack type
struct Stack
{
int size;
int top;
struct node* *array;
};
// A utility function to create a stack of given size
struct Stack* createStack(int size)
{
struct Stack* stack =
(struct Stack*) malloc(sizeof(struct Stack));
stack->size = size;
stack->top = -1;
stack->array =
(struct node**) malloc(stack->size * sizeof(struct node*));
return stack;
}
// BASIC OPERATIONS OF STACK
int isFull(struct Stack* stack)
{ return stack->top - 1 == stack->size; }
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
void push(struct Stack* stack, struct node* node)
{
if (isFull(stack))
return;
stack->array[++stack->top] = node;
}
struct node* pop(struct Stack* stack)
{
if (isEmpty(stack))
return NULL;
return stack->array[stack->top--];
}
// Returns true if a pair with target sum exists in BST, otherwise false
bool isPairPresent(struct node *root, int target)
{
// Create two stacks. s1 is used for normal inorder traversal
// and s2 is used for reverse inorder traversal
struct Stack* s1 = createStack(MAX_SIZE);
struct Stack* s2 = createStack(MAX_SIZE);
// Note the sizes of stacks is MAX_SIZE, we can find the tree size and
// fix stack size as O(Logn) for balanced trees like AVL and Red Black
// tree. We have used MAX_SIZE to keep the code simple
// done1, val1 and curr1 are used for normal inorder traversal using s1
// done2, val2 and curr2 are used for reverse inorder traversal using s2
bool done1 = false, done2 = false;
int val1 = 0, val2 = 0;
struct node *curr1 = root, *curr2 = root;
// The loop will break when we either find a pair or one of the two
// traversals is complete
while (1)
{
// Find next node in normal Inorder traversal. See following post
// http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/
while (done1 == false)
{
if (curr1 != NULL)
{
push(s1, curr1);
curr1 = curr1->left;
}
else
{
if (isEmpty(s1))
done1 = 1;
else
{
curr1 = pop(s1);
val1 = curr1->val;
curr1 = curr1->right;
done1 = 1;
}
}
}
// Find next node in REVERSE Inorder traversal. The only
// difference between above and below loop is, in below loop
// right subtree is traversed before left subtree
while (done2 == false)
{
if (curr2 != NULL)
{
push(s2, curr2);
curr2 = curr2->right;
}
else
{
if (isEmpty(s2))
done2 = 1;
else
{
curr2 = pop(s2);
val2 = curr2->val;
curr2 = curr2->left;
done2 = 1;
}
}
}
// If we find a pair, then print the pair and return. The first
// condition makes sure that two same values are not added
if ((val1 != val2) && (val1 + val2) == target)
{
printf("\n Pair Found: %d + %d = %d\n", val1, val2, target);
return true;
}
// If sum of current values is smaller, then move to next node in
// normal inorder traversal
else if ((val1 + val2) < target)
done1 = false;
// If sum of current values is greater, then move to next node in
// reverse inorder traversal
else if ((val1 + val2) > target)
done2 = false;
// If any of the inorder traversals is over, then there is no pair
// so return false
if (val1 >= val2)
return false;
}
}
// A utility function to create BST node
struct node * NewNode(int val)
{
struct node *tmp = (struct node *)malloc(sizeof(struct node));
tmp->val = val;
tmp->right = tmp->left =NULL;
return tmp;
}
// Driver program to test above functions
int main()
{
/*
15
/ \
10 20
/ \ / \
8 12 16 25 */
struct node *root = NewNode(15);
root->left = NewNode(10);
root->right = NewNode(20);
root->left->left = NewNode(8);
root->left->right = NewNode(12);
root->right->left = NewNode(16);
root->right->right = NewNode(25);
int target = 28;
if (isPairPresent(root, target) == false)
printf("\n No such values are found\n");
getchar();
return 0;
}
I found one bug under Chen Pang answer otherwise it's perfect. Bug is under remove method. All other code is same except remove method under iterator
suppose we have tree, per Chen Pang answer its will not consider element 18. similarly for left iterator
10
20
15 25
13 18
class BinTreeIterator implements Iterator<BinTreeNode> {
Stack<BinTreeNode> stack;
boolean leftToRight;
public boolean hasNext() {
return !stack.empty();
}
public BinTreeNode next() {
return stack.peek();
}
public void remove() {
BinTreeNode node = stack.pop();
if (leftToRight) {
node = node.rightChild;
while (node.rightChild != null) {
stack.push(node);
BinTreeNode leftNode=node.leftChild;
while (leftNode != null) {
stack.push(leftNode);
leftNode= node.leftChild;
}
node = node.rightChild;
}
} else {
node = node.leftChild;
while (node.leftChild != null) {
stack.push(node);
BinTreeNode rightNode=node.rightChild;
while (rightNode != null) {
stack.push(rightNode);
rightNode= node.rightChild;
}
node = node.leftChild;
}
}
}
public BinTreeIterator(BinTreeNode node, boolean leftToRight) {
stack = new Stack<BinTreeNode>();
this.leftToRight = leftToRight;
if (leftToRight) {
while (node != null) {
stack.push(node);
node = node.leftChild;
}
} else {
while (node != null) {
stack.push(node);
node = node.rightChild;
}
}
}
public static boolean searchNumBinTree(BinTreeNode node, int num) {
if (node == null)
return false;
BinTreeIterator leftIter = new BinTreeIterator(node,true);
BinTreeIterator rightIter = new BinTreeIterator(node,false);
while (leftIter.hasNext() && rightIter.hasNext()) {
BinTreeNode left = leftIter.next();
BinTreeNode right = rightIter.next();
int sum = left.item + right.item;
if (sum == num) {
return true;
} else if (sum > num) {
rightIter.remove();
if (!rightIter.hasNext() || rightIter.next() == left) {
return false;
}
} else {
leftIter.remove();
if (!leftIter.hasNext() || leftIter.next() == right) {
return false;
}
}
}
return false;
}
private static class BinTreeNode{
BinTreeNode leftChild;
BinTreeNode rightChild;
}
}
public boolean nodeSum(Node root, int num){
/*
Just subtract the sum from current value of the node and find
the node with remainder.
*/
if(root==null){
return false;
}
int val=num-root.key;
boolean found=find(root,val);
if(found){
return true;
}
boolean lSum=nodeSum(root.left,num);
boolean rSum=nodeSum(root.right,num);
return lSum||rSum;
}
public boolean find(Node root, int k){//same as search
if(root==null){
return false;
}
if(root.key==k){
return true;
}
if(root.key<k){
return find(root.right,k);
}else{
return find(root.left, k);
}
}

Categories