recursion function keeps running and prints nothing - java

Long story short, I'm supposed to make a code that inserts, deletes, searches for and prints numbers in a skip list with the first node being negative infinity and the last node being positive infinity (-inf > (...) > inf). I called my search function from my insert function to find a spot to insert any new nodes (only after the third node has been inserted) and I initialize or reference my nodes outside the main function rather than inside of it (although I'm debating on whether or not I should do the latter instead). However one of my functions may be stuck in a loop.
static Node search(double item, double max) {
Node head2 = head;
head2 = Start(head2, max);
//starts at the first highest node in the skiplist
//{... } //find a specific node in a skiplist
return head2;
}
//find first highest node for the search function
static Node Start(Node head2, double max) {
System.out.println(head.key + " " + head.level);
Node s = new Node();
if (head2.max < max) {
s = Start(head2.next, max);
return s;
}
else if (head2.max >= max && head2.inf == false) {
if (head2.level < head2.max) {
s = Start(head2.up, max);
return s;
}
else if (head2.level == head2.max) {
s = head;
return s;
}
}
return s;
}
The start function is called from the search function (called in order of main > double insert > Node search > Node start) and it is supposed to find the first node of the highest level. Once it does so, It returns that node to the search function so it can start it's search from there. But when called, it simply goes blank and nothing happens despite continuing to run. When I put in a print function to determine the problem, it simply prints the first node's key and 1st level and goes blank from there. UPDATE: I've learned that the function is able to find the node but it can't return it via recursion. I would like to find a way to fix that.

The problem was actually in my search function.
for(j = max; j >= 1; j--) {
while(head2.next != last && head2.key != item && i == 0) {
if(item > head2.key && head2.next != last) {
head2 = head2.next;
}
else if(item < head2.key || head2.next == last) {
head2 = head2.prev;
i = 1;
}
}
(...)}
this was the function that kept looping so I had to change the statement for while by having it say this instead
while(head2.next != last && head2.key < item && head2.inf != true && i == 0)

Related

Checking a tree to be a BST

Here is my attempt to check whether a tree is a BST or not:
public boolean isBST() {
return isBSTRecursively(this.root, new Max());
}
class Max {
int value;
}
private boolean isBSTRecursively(Node node, Max max) {
if (node == null) return true; // to handle null root
// to handle scenario when both child nodes are absent
if(node.getLeft() == null && node.getRight() == null) {
max.value = node.getValue();
return true;
}
// if left child is absent, we only investigate right subtree
if(node.getLeft() == null) {
Max rightMax = new Max();
boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
max.value = Math.max(node.getValue(), rightMax.value);
if(isRightBST && node.getValue() < rightMax.value) {
return true;
} else {
return false;
}
} else {
Max leftMax = new Max();
boolean isLeftBST = isBSTRecursively(node.getLeft(), leftMax);
// if right child is absent, we only investigate left subtree
if(node.getRight() == null) {
max.value = Math.max(node.getValue(), leftMax.value);
if(isLeftBST && node.getValue() > leftMax.value) {
return true;
} else {
return false;
}
} else {
// we investigate both left and right subtrees
Max rightMax = new Max();
boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
max.value = Math.max(Math.max(leftMax.value, node.getValue()), rightMax.value);
if(isLeftBST && isRightBST && leftMax.value < node.getValue() && node.getValue() < rightMax.value) {
return true;
} else {
return false;
}
}
}
Code works fine as tested with multiple test cases.
But I am not sure if this is a good, clean approach.
Recursive method is big it seems. I am dealing with scenarios like null left node, null right node, node itself null, both child nodes null etc. separately. I guess they all can be handled in a much smaller, and cleaner way.
Moreover, I am always more inclined towards iterative approach(I generally find it better to visualize). Would that be better here (given it can be done iteratively)?
Any suggestions?
A cleaner recursive approach
You could use a bounded approach, i.e. have two variables for every recursion: min and max.
Initially min = INT_MIN and max = INT_MAX
if node = NULL then return True because an empty BST is a BST
else check if node.val < min or node.val > max if this condition is True then tree is not a BST, return False Notice : the strict inequality > and < are used as BST doesn't allow duplicate elements.
recurse for left : recur(node.left) with min remaining the same and max = node.val - 1 because the left subtrees should have values not greater than node.val - 1.
The max cannot be node.val because BST cannot have duplicate elements.
Store the boolean return value in say left
recurse for right : recur(node.right) with min = node.val + 1 and max remaining the same.
The right subtrees should have values not less than node.val + 1.
Store the boolean return value in say right
return left && right
#Aditya gave the ingredients of the more elegant solution.
It is generally not forbidden for a binary search tree to have duplicate values, so there should no be reduction of the "window" with 1.
Here is suggested code:
public boolean isBST() {
return isBSTRecursively(this.root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
private boolean isBSTRecursively(Node node, int min, int max) {
return node == null
|| node.getValue() >= min && node.getValue() <= max
&& isBSTRecursively(node.getLeft(), min, node.getValue())
&& isBSTRecursively(node.getRight(), node.getValue(), max);
}

Binary Tree branch sums without recursion

I am trying to calculate a sum of each branch of a binary tree without using recursion. I'm trying to use a stack and can't figure out how to fix my code to get the right sums.
public static List<Integer> branchSums(BinaryTree root) {
LinkedList<BinaryTree> toVisit = new LinkedList<>();
BinaryTree current = root;
List<Integer> sums = new ArrayList<>();
int sum = 0;
while (current != null || !toVisit.isEmpty()) {
while (current != null) {
sum += current.value;
toVisit.push(current);
current = current.left;
}
current = toVisit.pop();
// if found leaf add sum to results and decrement sum by current node
if (current.left == null && current.right == null) {
sums.add(sum);
sum -= current.value;
}
current = current.right;
}
return sums;
}
Example input:
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ /
8 9 10
Example output [15, 16, 18, 10, 11]
Issue with your code is you are not keeping track of the node which
has been last popped from your stack.
Here is the updated code:
public static List<Integer> caculateSum(BinaryTree root) {
List<Integer> sums = new ArrayList<>();
int sum=0;
BinaryTree current = root, popped=null;
Stack<BinaryTree> s = new Stack<BinaryTree>();
while(current!=null ) {
//checking if last node popped from stack is not equal to left or right node of current node
if(popped==null||((current.left!=null && !current.left.equals(popped)) && (current.right!=null && !current.right.equals(popped)))) {
while(current != null) {
sum+=current.value;
s.push(current);
current = current.left;
}
}
current=s.peek();
if(current.right == null) {
//if current node is leaf node
if(current.left == null) {
sums.add(sum);
}
sum-=current.value;
popped = current;
s.pop();
} else if(current.right!=null && current.right.equals(popped)){
//if current node both left and right nodes have been processed
sum-=current.value;
popped = current;
s.pop();
}else {
//if current node right part is not processed
sum+=current.right.value;
s.push(current.right);
}
if(s.isEmpty()) {
break;
}
current=s.peek();
}
return sums;
}
Will explain this by taking an example. Suppose we have given binary tree
1,2,9,3,7,null,8,5
Here in above code apart from old variables a new variable popped is used which keeps track of last element which is popped out from stack.
So, following are the major steps :
Starting from current node first we are checking if current node left is not equal to popped (if it is equal it means that current node left part is already processed so we don't need to process it again). Same we are checking if current node right node is not equal to popped node (if it is equal it means we have already processed right node of current node which indirectly means left node is also processed).
Now for the top node of stack which is current node we check :
If its right node is null If it is true it means either current
node is leaf node or it is an already processed node whose right
node is null (like in our example node with value of 3). If it is
leaf we add it in our sums list. Also, for both cases we remove
this top node and subtract its value from current sum value
(This thing has been done in above code as well) .Along with this we
will keep track of popped element from stack in popped variable.
If its right is not null but its right node is equal to popped
node This happens when in last pass of while loop we had processed
this right node. This means for top node of stack both left and
right node have been processed and hence we pop this node and keep
track of it in popped variable.
Else we push the right node of top element of stack in stack.
At the end for above example , sums variable will store result as [11, 10, 18]
I attempted this for fun and was surprised I didn't see any actual solutions. The following is in Kotlin but can easily be transcribed into Java. The trick was to add state to the Node itself to mark it as consumed before you popped it, otherwise there was no value there to check when going down another branch.
This might be useful in super rare cases to prevent stack overflow? This will still run in O(N) but takes more space with the stacks, and will visit a node twice, once to traverse and once to pop.
open class BinaryTree(value: Int) {
var value = value
var left: BinaryTree? = null
var right: BinaryTree? = null
var consumed: Boolean = false
}
fun branchSums(root: BinaryTree): List<Int> {
var sumList = ArrayList<Int>()
var nodeStack = ArrayList<BinaryTree>()
var valueStack = ArrayList<Int>()
nodeStack.add(root)
while(!nodeStack.isEmpty()) {
val node = nodeStack.get(nodeStack.size-1)
if (node.consumed) {
valueStack.removeAt(valueStack.size - 1)
nodeStack.removeAt(nodeStack.size - 1)
continue
}
valueStack.add(node.value)
if (node.right == null && node.left == null) {
var sum = 0
for (value in valueStack) {
sum += value
}
sumList.add(sum)
}
if (node.right != null) {
nodeStack.add(node.right!!)
}
if (node.left != null) {
nodeStack.add(node.left!!)
}
node.consumed = true
}
return sumList
}
You can have this method:
public static int getBranchSum(Node root){
Queue<Node> q = new LinkedList<>();
q.add(root);
int sum=0;
while (!q.isEmpty()) {
Node curNode = q.poll();
sum+=curNode.data;
if(curNode.left==null || curNode.right==null)
curNode.visited=true;
if(curNode.left != null && curNode.left.visited)
curNode.visited=true;
if(curNode.left!=null && !curNode.left.visited)
q.add(curNode.left);
else if(curNode.right!=null && !curNode.right.visited)
q.add(curNode.right);
}
root.visited=false;
return sum;
}
Then call it below in a while loop as long as the output is not equal the root data.
boolean flag=true;
List<Integer> list = new ArrayList<>();
while(flag){
int result =getBranchSum(root);
if(result == root.data)
flag=false;
else
list.add(result);
}
System.out.println(list);
However the above the working only if we have a visited boolean in the node:
class Node{
Node left,right;
int data;
boolean visited = false;
Node(int data){
this.data=data;
left=right=null;
}
Branch sum without recursion
def branchSums(root):
cs=0
stack=[{"node":root,"cs":cs}]
sums=[]
while(len(stack)>0):
node_info=stack.pop()
node,cs=node_info["node"],node_info["cs"]
if node is None:
continue
cs=cs+node.value
if node.left is None and node.right is None:
sums.append(cs)
print(sums)
stack.append({"node":node.right,"cs":cs})
stack.append({"node":node.left,"cs":cs})
return sums

How should I implement removal of rightmost half of my custom Linkedlist

Write the method removeRightmostHalf member of the class LinkedList. Do not call any methods of the class and do not use any auxiliary data structures.
If l contains A! B! C! D! E, then after calling l.removeRightmostHalf(), l becomes A! B! C.
int size = 0 ;
int halfSize = 0;
current = head;
while (current.next != null) {
++size;
current=current.next;
}
++size;
if (size % 2 == 0) {
halfSize = (size / 2);
for (int i = halfSize + 1; i < size; i++) {
}
}
I do not know how I will remove inside for loop.
Any help!
I would suggest you to use two pointers, slow and fast pointer. Initially both will be pointing to the start of the linked list.
The slow pointer will move one node at a time.
The fast will move two node a time.
The moment you see that fast pointer has reached the end of the list, just mark the slow pointer node as end of the list, by setting next=null;
Important note that, the discovery of the end of the list will be depend on the even/odd size of the list. So design and test with both cases.
This will work , when you reach the half of the list just cut the link with the rest of it.
public void removeRightMost() {
int size = 0;
int halfSize = 0;
current = head;
while (current!= null) {
size++;
current = current.next;
}
if (size % 2 == 0) {
halfSize = (size / 2);
int count = 0;
current = head;
/* if the number of elements is even you need to decrease the halfSize 1 because
you want the current to reach the exactly half if you have 4 elements the current
should stop on the element number 2 then get out of the loop */
while (count < halfSize-1) {
current = current.next;
count++;
}
current.next=null; //here the process of the deletion when you cut the rest of the list , now nothing after the current (null)
}
else {
halfSize = (size / 2);
int count = 0;
current = head;
while (count < halfSize) {
current = current.next;
count++;
}
current.next=null;
}
current=head; // return the current to the first element (head)
}
good luck

Size of a binary tree with non recursive method Java

Hello I'm trying to write a non recursive method for getting the size of a node since recursion in Java is expensive. This would include the number of child nodes + 1 (itself). I've converted an C implementation How can I get number of leaf nodes in binary tree non-recursively? in to Java but it's not correct.
Edit: algorithm for counting the size of binary tree, non recursively.
public int size(Node n) {
Stack<Node> sizeStack = new Stack();
int count = 1;//includes the n node
if(n == null) {
return 0;
}
sizeStack.push(n);
while(!sizeStack.isEmpty()){
node = sizeStack.pop();
while(node != null) {
count++;
if(node.right != null){
sizeStack.push(node.right);
}
node = node.left;
}
}
return count;
}
Your algorithm is counting leaf nodes. Your own wish was to count all the nodes. An algorithm for counting leaf nodes only adds to the counter when it pops a leaf node, and that's true both for Java and for C. So actually your program is good - but not for the problem you have defined.
In order to count all the nodes, you have to increment the counter every time you pop a node from the stack. This means you have to push all the nodes, rather than loop the way you have for the leaf nodes.
If you want to save on push operations (which is the only reason why this algorithm will be better than recursion, unless the tree is unbalanced towards the right) you should just increment the counter for every node that you are examining, but keep the basic loop as it was.
public int size(Node n) {
Stack<Node> sizeStack = new Stack();
int count = 1;//includes the n node
if(n == null) {
return 0;
}
sizeStack.push(n);
while(!sizeStack.isEmpty()){
node = sizeStack.pop();
while(node != null) {
count++;
if(node.right != null){
sizeStack.push(node.right);
}
node = node.left;
}
}
return count;
}
Here is a C implementation. RealSkeptic's method above was not that intuitive to me. I provide comments and it should be pretty easy to follow.
int sizeOfBsTree_nonRec(TreeNode *root)
{
if (root == NULL) {
return 0;
}
int size = 0;
Stack S;
initializeStack(&S);
// Push to the stack all Nodes in the (sub)tree and
// increase the counter when you pop one out
push(root, &S);
while(!isStackEmpty(&S)){
root = pop(&S);
size++;
if (root->right != NULL)
push(root->right, &S);
if (root->left != NULL)
push(root->left, &S);
}
return size;
}

linked list print every nth integer method

I need to write a method for a linked list class that:
Print the contents of every "nth" node in the list. Obtain the "n" from the user, ensure it is
greater than 0.
How would i go about doing this?
public void nthNode (int n) {
if (n <= 0) {
System.out.println("error");
} else {
//bla
}
}
public void nthNode (int n) {
if (n <= 0) {
System.out.println("error");
} else {
for (int i = 0; i < size(); i += n) {
//LinkedList#get(i);
}
}
}
Iterate over every element in the list. If the index of the current item is evenly divisible by n then print the element. You can check for even divisibility by using the modulus operator (% in Java)
You main motive is to print the data of nodes when the counter will be a multiple of n.
so instead of checking the mod on data, u need to do it on counter and have the mod check with n.
Iterating over the link list (using say curr pointer) using while loop. Check for condition curr.next!=null. initialize count to 0. While iterating count the number of nodes traversed till now. If the (count == n), then print the node data and initialize count to 0.
Assuming you have a node class of some sort:
public void nthNode( int n ){
if( n <= 0 ){
System.out.println( "error" );
} else {
Node e = new Node();
e = head;
int count = 0;
while( e != null ){
if( count == n ){
//do stuff
break;
}
e = e.next;
cout++;
}
}
Sorry kinda sloppy but that's the gist.

Categories

Resources