Stack Overflow error: How would I write this method Iteratively? - java

I'm getting a Stack overflow error for the following method at the recursive call. I think I need to make it iterative in order for it to work. How would I write the following method iteratively?
Node myMethod(String foo, Node p) {
if(p == null) {
p = new Node(foo);
p.link = spot;
spot = p;
p.calc[bar] = 1;
return p;
} else if(foo.equals(p.origin)) {
p.calc[bar] = p.calc[bar] + 1;
return p;
} else {
while (p.next == null & foo.equals(p.origin)){
p = p.next;
}
p.next = myMethod(foo, p.next);
return p;
}
}
p is a Node class that has String foo, String origin, Node link, Node next, and int Array calc[]. bar is an int. spot is a random node.
This is what I have tried so far
Node myMethod(String foo, Node p) {
if(p == null) {
p = new Node(foo);
p.link = spot;
spot = p;
p.calc[bar] = 1;
return p;
} else if(foo.equals(p.origin)) {
p.calc[bar] = p.calc[bar] + 1;
return p;
} else {
while (p.next == null & foo.equals(p.origin)){
p = p.next;
}
//instead of doing recursion on: p.next = myMethod(foo, p.next);. I tried the following:
if (p.next == null){
p.next = new Node(foo);
p.next.link = spot;
spot = p.next;
p.next.calc[bar] = 1;
} else if (foo.equals(p.next.origin)){
p.next.calc[bar] = p.next.calc[bar] + 1;
} else {
while (p.next.next == null & foo.equals(p.next.origin)){
p.next = p.next.next;
}
}
}
return p;
}

Although your iterative-try probably could be written better, this is a good try. However, look here:
else {
while (p.next == null & foo.equals(p.origin)){ //HERE! Check the while argument.
p = p.next;
} //instead of doing recursion on: p.next = myMethod(foo, p.next);. I tried the following:
…
The while loop will stop if p.next is null or foo does not equal p.origin. Now the basic approach would be to serve three cases here:
what to do when p.next != null (first while condition)
what to do when !foo.equals(p.origin) (second while condition) //you did not write it.
what to do when p.next != null && !foo.equals(p.origin)
If your while conditions are correct (ones you want them to be), you need to serve all cases for which the while loop may have stopped and that should be end of your algorithm. If it is not, rethink your while loop condition.

I'm still not entirely shure what you are trying to do and this code looks like bad programming style but maybe it will do what you need.
Node myMethod(String foo, Node p) {
while(p != null) {
if(foo.equals(p.origin)) {
p.calc[bar] = p.calc[bar] + 1;
break;
}
p = p.next;
}
if(p == null) {
p = new Node(foo);
p.link = spot;
spot = p;
p.calc[bar] = 1;
}
return p;
}

Related

How to implement skiplist in java (adding values, checking for values)?

I want to write a method that allows me to insert a value to the list (generic implementation). Furthermore i want to check wether a value in already in the list or not. I just want to know wether this is how its supposed to be or not.
In order to check wether a value is already contained within the list:
public boolean contains(T value) {
boolean searchedValue;
if (head == null || baseListLength == 0) {
searchedValue= false;
} else {
IndexListEntry<T> blub= head;
while ((blub.next != null) && (blub.next.value.compareTo(value) <= 0)) {
value= blub.next;
}
searchedValue= baseList.contains(value, blub.pointer);
}
return searchedValue;
}
and to add any value to the list:
public boolean addValue(T value) {
BaseListEntry<T> offs= baseList.add(value);
if (indexListLength < indexMaxLength) {
if (head == null) {
head = new IndexListEntry<T>(value, null, offs);
} else {
IndexListEntry<T> temp= head;
while ((temp.next != null) && (temp.next.value.compareTo(value) < 0)) {
temp= temp.next;
}
if (temp.next == null) {
temp.next = new IndexListEntry<T>(value, null, offs);
} else {
temp.next = new IndexListEntry<T>(value, temp.next, offs);
}
}
indexListLength++;
} else {
IndexListEntry<T> currentIndex = head.next;
int intervalWidth = baseListLength / indexMaxLength;
int intervalAdj = baseListLength % indexMaxLength;
int indexPosition = 0;
for (int i = 1; i < indexMaxLength; i++) {
int rip= 0;
if (intervalAdj - i >= 0)
rip= 1;
indexPosition = indexPosition + intervalWidth + rip;
BaseListEntry<T> newIndexTarget = baseList.getBaseListEntry(indexPosition);
currentIndex.pointer = newIndexTarget;
currentIndex.value = newIndexTarget.value;
currentIndex = currentIndex.next;
}
}
return true;
}
Are there any other methods to accomplish that goal? is my code somewhat correct. I am doubting everything I code right now and I kinda need confirmation from someone who knows more than me about this.
This is of course not everything i got. there are more classes to it but these are not the problem at hand so i dont thnk i need to upload that code as well.

Else master will never be excuted in successor() in treemap

I'm learning sourcecode of remove() in treemap. But there is something i can't understand.
//....................ignore major codes,left these
private void deleteEntry(Entry<K,V> p) {
if (p.left != null && p.right != null) {
Entry<K,V> s = successor(p);
p.key = s.key;
p.value = s.value;
p = s;
}
}
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {`enter code here`
if (t == null)
return null;
else if (t.right != null) {
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
I felt confused in deleteEntry function, p has 2 kids. P.left and P.right all
aren't null.
but why dose it judge that t.right is not empty in successor function?
I mean that it's absoulte fact. And because t.right must be
not null. Codes never be excuted in else master in successor function.
Who call tell me where is my problem? Thank you ,guys.
If you look at TreeMap.java , you will get to know that successor is getting called from many places, delete() is just one such place.

Searching a custom linked list - Which is the better method?

So I have two implementation of a method that searches a custom linked list with name as input and either gets the mark associated with the name if the name is found or returns -1.
public int getMark (String name) {
Node p = head;
while ((p != null) && !(p.getName().equals(name)){
p = p.getNext();
}
if (p == null){
return - 1;
}
else
{
return p.getMark();
}
}
OR
public int getMark(String name){
Node p = head;
if(head == null)
{
return -1;
break;
}
while(p != null)
{
if(p.getName().equals(name)
{
return p.getMark();
}
else
{
return -1;
}
p = p.getNext();
}
}
They both do the job but I want to know which solution is better. I personally find the first solution confusing and not logically sound.
Your first code is not seems better as if any of your node may be null then it will return -1 and not check further,
Also your second logic is little bit complex it should be as below which can perform better.
public int getMark(String name){
Node p = head;
if(head == null)
{
return -1;
}
while(p != null)
{
if(p.getName().equals(name)
{
return p.getMark();
}
p = p.getNext();
}
return -1;
}
Your second version won't work unless the head contains the correct one and the first version seems a bit too much. Have a look at this: It's faster and (in my opinion) more readable
public int getMark (String name) {
Node p = head;
//Check if head is the correct one
if (name.equals(p.getName())){
return p.getMark();
}
while (hasNext(p)){
p = p.getNext();
if (name.equals(p.getName())){
return p.getMark();
}
}
//Ending up here means we didn't find it
return -1;
}
private boolean hasNext(Node p){
return p.getNext() != null;
}
Note that I'm assuming head and 'name' are not null, otherwise this won't work of course
This would be my approach as it's concise and readable (in my opinion). Pretty much a variation of your first implementation. Arguably you could return -1 if the head is null.
public int getMark(String name) {
Node p = head;
while (p != null && !p.getName().equals(name)) {
p = p.next;
}
return p != null ? p.getMark() : -1;
}

Counting the number of nodes in Leaf diagram

Been working on this for while with no luck. Hopefully someone can point in the right direction.
Code:
public class BST {
public BTNode<Integer> root;
int nonLeafCount = 0;
int depthCount = 0;
public BST() {
root = null;
}
class BTNode<T> {
T data;
BTNode<T> left, right;
BTNode(T o) {
data = o;
left = right = null;
}
public String toString() {
return String.valueOf(data);
}
}
}
The easy way to traverse a tree without recursive calls is to use a stack. Push the root on the stack, then enter a loop that - so long as the stack is not empty - pops a node from the stack and pushes the non-null children of that node. It's pretty obvious that this will eventually push every node onto the stack exactly once and pop it exactly once. Now all you need to do is count the popped nodes that have at least one child. Putting this together,
public int nonleaves() {
int nonLeafCount = 0;
BTNode<Integer> [] stack = new BTNode[2];
int p = 0;
stack[p++] = root; // push root
while (p != 0) {
BTNode<Integer> node = stack[--p]; // pop
if (node.left != null || node.right != null) ++nonLeafCount;
if (p + 1 >= stack.length) stack = Arrays.copyOf(stack, 2 * stack.length);
if (node.right != null) stack[p++] = node.right; // push right
if (node.left != null) stack[p++] = node.left; // push left
}
return nonLeafCount;
}
Note that in accordance with your description, I used a simple Java array for a stack, growing it by a factor of 2 whenever it fills up. Integer p is the stack pointer.
Also, this code assumes the root is non-null. If the root can be null, add a check at the start and return 0 in that case.
NB it's possible to traverse without even a stack by several methods, although at the cost of changing the tree during traversal. (It's back in its original shape when the traversal is complete.) The nicest IMO is Morris's algorithm, but all of them are considerably more complicated than the stack. Since it seems you're a new programmer, figure out the stack method first.
Edit
To find max depth:
public int maxDepth() {
int max = 0;
Pair<Integer> [] stack = new Pair[2];
int p = 0;
stack[p++] = new Pair(root, 1);
while (p != 0) {
Pair<Integer> pair = stack[--p];
if (pair.depth > max) max = pair.depth;
if (p + 1 >= stack.length) stack = Arrays.copyOf(stack, 2 * stack.length);
if (pair.node.right != null)
stack[p++] = new Pair(pair.node.right, 1 + pair.depth);
if (pair.node.left != null)
stack[p++] = new Pair(pair.node.left, 1 + pair.depth);
}
return max;
}
private static class Pair<T> {
BTNode<T> node;
int depth;
Pair(BTNode<T> node, int depth) {
this.node = node;
this.depth = depth;
}
}
Finally, I'd be remiss if I didn't point out that we can do some algebra on the algorithm to eliminate some tiny inefficiencies. You'll note that after the left child is pushed onto the stack, it is certain to be popped in the next loop iteration. The root push/pop is similar. We might as well set node directly. Also, there are some redundant comparisons. The details are too much for this note, but here is a reworked non-leaf counter (untested but ought to work fine):
public int nonleaves() {
int nonLeafCount = 0;
BTNode<Integer>[] stack = new BTNode[1];
int p = 0;
BTNode<Integer> node = root;
for (;;) {
if (node.left == null) {
if (node.right == null) {
if (p == 0) break;
node = stack[--p];
} else { // node.right != null
++nonLeafCount;
node = node.right;
}
} else { // node.left != null
++nonLeafCount;
if (node.right != null) {
if (p >= stack.length) {
stack = Arrays.copyOf(stack, 2 * stack.length);
}
stack[p++] = node.right;
}
node = node.left;
}
}
return nonLeafCount;
}
You can see that to eek out a tiny bit of efficiency we lose a lot of simplicity. This is almost always a bad bargain. I recommend against it.
A possible solution:
public class BST<T> {
public BTNode<T> root;
int depthCount = 0;
public BST() {
root = null;
}
public int nonleaves() { // Method must be declared like this. No
// parameters.
BTNode<T> current = root;
BTNode<T> previous = null;
int nonLeafCount = 0;
while (current != null) {
if (previous == current.parent) { // this includes when parent is
// null, i.e. current is the
// root.
previous = current;
if (current.left != null) {
nonLeafCount++;
current = current.left;
} else if (current.right != null) {
nonLeafCount++;
current = current.right;
} else {
current = current.parent;
}
} else if (previous == current.left) {
previous = current;
if (current.right != null) {
current = current.right;
} else {
current = current.parent;
}
} else {
// previous==current.right
previous = current;
current = current.parent;
}
}
return nonLeafCount;
}
private static class BTNode<T> {
BTNode<T> left, right, parent;
/* ... */
}
}
Using stacks:
public class BST2<T> {
public BTNode<T> root;
int depthCount = 0;
public BST2() {
root = null;
}
public int nonleaves() { // Method must be declared like this. No
// parameters.
BTNode<T> current = root;
BTNode<T> previous = null;
int nonLeafCount = 0;
MyStack myStack = new MyStack(); // New empty stack
while (current != null) {
if (previous == myStack.top()) { // this includes when stack is
// empty, i.e. current is the
// root.
myStack.push(current);
previous = current;
if (current.left != null) {
nonLeafCount++;
current = current.left;
} else if (current.right != null) {
nonLeafCount++;
current = current.right;
} else {
myStack.pop();
current = myStack.top();
}
} else if (previous == current.left) {
previous = current;
if (current.right != null) {
current = current.right;
} else {
myStack.pop();
current = myStack.top();
}
} else {
// previous==current.right
previous = current;
myStack.pop();
current = myStack.top();
}
}
return nonLeafCount;
}
private static class BTNode<T> {
BTNode<T> left, right;
/* ... */
}
}

Why won't my delete function delete the node out of the BST?

I've spent hours trying to figure it out. I've checked and the delete function does find the node, but when I try to delete it by setting it as null or equal to a child node it doesn't change the tree at all when I print it out for a second time. Can anyone help me figure out what I've done wrong or at least guide me to what I need to do to fix it?
class BST {
Node root;
void BST () {
root = new Node("B");
insert (root, "A");
insert (root, "D");
insert (root, "C");
inOrder (root);
System.out.println (" ");
delete (root, "D");
//root.LEFT = null;
inOrder (root);
}
void insert (Node n, String newKEY) {
if (n.KEY.compareTo(newKEY) > 0) {
if (n.LEFT == null) n.LEFT = new Node(newKEY);
else if (n.LEFT != null && n.LEFT.KEY.compareTo(newKEY) < 0) n.LEFT = new Node(n.LEFT, newKEY, null);
else insert (n.LEFT, newKEY);
}
if (n.KEY.compareTo(newKEY) < 0) {
if (n.RIGHT == null) n.RIGHT = new Node(newKEY);
else if (n.RIGHT != null && n.RIGHT.KEY.compareTo(newKEY) > 0) n.RIGHT = new Node(null, newKEY, n.RIGHT);
else insert (n.RIGHT, newKEY);
}
else if (n.KEY.compareTo(newKEY) == 0) n.C++;
}
void delete (Node n, String s) {
// Visit, check if proper node, if so then delete
if (n.KEY.compareTo(s) == 0) {
System.out.println (n.KEY);
// Deleting a node with no children
if (n.LEFT == null && n.RIGHT == null) n = null;
// Deleting a node with only left child
else if (n.RIGHT == null) n = n.LEFT;
// Deleting a node with only right child
else if (n.LEFT == null) n = n.RIGHT;
// Deleting a node with two children
else deleteNode_Two_Children (n, s);
}
// Left
else if (n.KEY.compareTo(s) > 0) delete (n.LEFT, s);
// Right
else if (n.KEY.compareTo(s) < 0) delete (n.RIGHT, s);
}
boolean find (Node n, String s) {
if (n.KEY.compareTo(s) > 0) {
if (n.LEFT == null) return false;
else if (n.LEFT != null && n.LEFT.KEY.compareTo(s) < 0) return false;
else find (n.LEFT, s);
}
if (n.KEY.compareTo(s) < 0) {
if (n.RIGHT == null) return false;
else if (n.RIGHT != null && n.RIGHT.KEY.compareTo(s) > 0) return false;
else find (n.RIGHT, s);
}
else if (n.KEY.compareTo(s) == 0) return true;
return false;
}
void deleteNode_Two_Children (Node n, String st) {
Node s = getSuccessor(n);
n = new Node (n.LEFT, s.KEY, s.C, n.RIGHT);
delete (s, st);
}
Node getSuccessor (Node n) {
Node temp = new Node();
while (n.LEFT != null) {
temp = n.LEFT;
n = temp;
}
return temp;
}
void inOrder (Node n) {
// Left
if (n.LEFT != null) inOrder (n.LEFT);
// Visit
System.out.print (n.KEY + " - " + n.C + ", ");
// Right
if (n.RIGHT != null) inOrder (n.RIGHT);
}
public static void main(String args[]){
BST t = new BST();
t.BST();
}
}
class Node {
String KEY;
int C;
Node LEFT;
Node RIGHT;
Node (String key) {
KEY = key;
C = 1;
LEFT = null;
RIGHT = null;
}
Node (Node L, String key, Node R) {
LEFT = L;
RIGHT = R;
KEY = key;
C = 1;
}
Node (Node L, String key, int c, Node R) {
LEFT = L;
RIGHT = R;
KEY = key;
C = c;
}
Node () {
KEY = null;
C = 0;
LEFT = null;
RIGHT = null;
}
// If 'this' is less than 'other', a negative number will be returned,
// 0 if equal
// Positive number if 'this' is greater.
int compare (Node other) {
return this.KEY.compareTo(other.KEY);
}
boolean equals (Node other) {
return this.KEY.equals(other.KEY);
}
}
The problem is your assumption that setting n to null will remove the node. Consider the following:
Object x = new Object();
public void someMethod(Object o) {
o = null;
}
This won't modify x. Java is pass-by-value, where o is the reference to some Object. You can certainly modify the internals of o through o's methods:
o.setValue(1);
This works because the value of o is really some address on the heap, which isn't being modifed. You can't overwrite o itself (eg, you can't set it to null or a new Object()). In order for you to delete a node, you must find the node's parent and set it's left or right child (whichever one you with to remove) and set that to null. Also, if that node has children, you have to make sure they aren't removed just because their parent is removed.

Categories

Resources