i am trying to learn abit about recursive methods and is writing a method for my binary tree that counts the sum of all the integers in the tree my code works fine and all but i am still abit confused about how the application knows when to stop. my code looks like the this:
public int sum(){
return sum(overallRoot);
}
private int sum(IntTreeNode root) {
if (root == null) {
return 0;
}else {
return root.data + sum(root.left) + sum(root.right);
}
}
(the above code is from my nodeTree class)
The next code is from my main class:
public class TreeClient {
/**
* #param args
*/
public static void main(String[] args) {
IntTree tree = new IntTree(12);
System.out.println(tree.sum());
}
}
So the question is (maybe for many quite simple) but how does my application know when to stop? ive tried with simple system out prints to figur out but as far as my understanding is right now the method would call it self in an endless loop?
hope someone has time to respond!
In any recursive program, your iteration stops when a base condition is reached.. Here your base condition is : -
if (root == null) {
return 0;
}
So, when your root.left and root.right, in the following return statement in else block both becomes null, you have reached your base condition, and hence your loop stops..
return root.data + sum(root.left) + sum(root.right);
Pretty simple really
Take the line from the sum function:
return root.data + sum(root.left) + sum(root.right);
When you get to the bottom of the tree, root.left will be null, and so will root.right. Thus, when the above line calls sum(root.left) the sum function drops into the other half of the if statement:
return 0;
Thus, the sum function no longer calls itself, and so stops recursing
The answer is that it does not go into an endless loop because there is a condition when it does not call itself recursively anymore.
The condition is
if (root == null)
when it does
return 0;
rather than calling itself again
return root.data + sum(root.left) + sum(root.right);
Related
I have a piece of code that I need insight on, I don't want to know the correct solution of the problem. I just want to know why is my concept failing.
So the function is to check if a binary tree is BST or not. I need to return 1 in case it is and 0 otherwise. My code is as below
int isBST(Node root) {
if(root == null)
return 1;
if(root.left!=null) {
if(root.left.data<root.data)
isBST(root.left);
else
return 0; // line:a
}
if(root.right!=null) {
if(root.right.data<root.data)
isBST(root.right);
else
return 0;
}
return 1;
}
For this piece, when i have a binary tree as follows:
5
\
7
/
8
I expect it to reach 8 value and break at line:a but it return me 1 instead of 0. Now I know 0 gets returned to the parent calling method. But is it not terminating because I have made isBST call without capturing the return value?
Please dont point out if there are anyother bugs.
For the general case, your approach won't work. The way to test if a tree is a BST is to recursively check if the current node is greater than the maximum element of the left subtree, and smaller than the minimum element of the right subtree. Also, you're missing the returns in the recursive calls:
return isBST(root.left);
...
return isBST(root.right);
By the way, why are you returning 0 or 1 for this? use false or true instead, changing the return type to boolean.
You should check if the right data ist bigger than the current and return the value of the recursive call
if(root.right.data>root.data)
I see the following issues:
If (and only if) isBST(root.left) or isBST(root.right) is false, you need to return 0 (btw, why are you not using booleans?) immediately.
The condition root.right.data<root.data should be inverted: root.right.data>=root.data.
So here's the modified code (keeping the int return type):
int isBST(Node root) {
if(root == null)
return 1;
if(root.left!=null) {
if(root.left.data<root.data) {
if (isBST(root.left) == 0)
return 0;
} else
return 0;
}
if(root.right!=null) {
if(root.right.data>=root.data) {
if (isBST(root.right) == 0) {
return 0;
}
} else
return 0;
}
return 1;
}
I'm learning recursion now, and I thought I quite understood how recursion works, and then I saw this code, and my head is about to explode.
I know this simple recursion works like
public void recursivePrint(int number){
if(number == 0{
return;
}
System.out.println(number + " ");
recursivePrint(number - 1);
}
If the parameter "number"'s value is 2.
public void recursivePrint(2){
if(number == 0{
return;
}
System.out.print(2 + " ");
recursivePrint(2 - 1);
}
public void recursivePrint(1){
if(number == 0{
return;
}
System.out.print(1 + " ");
recursivePrint(1 - 1);
}
and then stops because it meets its base case.
What about this print all permutations of a string function?
private void permute(String str, int l, int r)
{
if (l == r)
System.out.println(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str,l,i);
permute(str, l+1, r);
str = swap(str,l,i);
}
}
}
There is a recursive call inside a for loop. If the input value is "ab", how does this recursion function work? Can you explain as I wrote above?
I got this code form geeksforgeeks, and there's a video for this, but I can't understand this since I don't know how loop works in recursion.
Using permute function you are generating strings where lth char is being replaced by one of the char following it. With the for loop inside it, you are touching onto each of those following characters one at a time.
With several call to permute, you are able to advance till the end position of the string, and that end is checked by if (l == r)
Take the case of abc.
abc
/ | \
Level 1 a(bc) b(ac) c(ba) (Here three new call to permute are made out of permute with l=1)
Goes on...
FYI, permutation isn't that simple to understand if you are new to recursion or programming. For easy understanding use pen-paper.
Recursion occurs when a method calls itself. Such a method is called recursive. A recursive method may be more concise than an equivalent non-recursive approach. However, for deep recursion, sometimes an iterative solution can consume less of a thread's finite stack space.
What is recursion:
In general, recursion is when a function invokes itself, either directly or indirectly. For example:
// This method calls itself "infinitely"
public void useless() {
useless(); // method calls itself (directly)
}
Conditions for applying recursion to a problem:
There are two preconditions for using recursive functions to solving a specific problem:
There must be a base condition for the problem, which will be the endpoint for the recursion. When a
recursive function reaches the base condition, it makes no further (deeper) recursive calls.
Each level of recursion should be attempting a smaller problem. The recursive function thus divides the problem into smaller and smaller parts. Assuming that the problem is finite, this will ensure that the recursion terminates.
In Java there is a third precondition: it should not be necessary to recurse too deeply to solve the problem;
The following function calculates factorials using recursion. Notice how the method factorial calls itself within the function. Each time it calls itself, it reduces the parameter n by 1. When n reaches 1 (the base condition) the function will recurse no deeper.
public int factorial(int n) {
if (n <= 1) { // the base condition
return 1;
} else {
return n * factorial(n - 1);
}
}
I know this is pretty straight forward code but wondering how exactly the internal working is.
public static int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
System.out.print(getHeight(root.left) +"\t");
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
For my understanding, I added print statement but it results the following.
printing root.left() prints this: 0 0 0 1 0 0 0
printing root.right() prints this: 0 0 2 0 0 3 0 0 2 0 0 0 1 0
Following is the Tree created in the main program:
TreeNode parent = new TreeNode(10);
parent.insertInOrder(2);
parent.insertInOrder(13);
parent.insertInOrder(5);
parent.insertInOrder(6);
parent.insertInOrder(15);
parent.insertInOrder(6);
How is this printing the above result and how is it working. If anyone can explain me with the above example, it would really help me.
I know how traversals work and how to print the tree but I really want to understand the above output. If anyone can help then it would be great.
void setLeftChild(TreeNode left)
{
this.left = left;
if(left == null)
{
left.parent = this;
}
}
void setRightChild(TreeNode right)
{
this.right = right;
if(right == null)
{
right.parent = this;
}
}
void insertInOrder(int d)
{
if(d <= data)
{
if(left == null)
{
setLeftChild(new TreeNode(d));
}
else
{
left.insertInOrder(d);
}
}
else{
if(right == null)
{
setRightChild(new TreeNode(d));
}
else{
right.insertInOrder(d);
}
}
size++;
}
You should create a function that outputs information about the tree. For example, this function does a preorder traversal, showing information about each node:
public static void ShowTree(TreeNode root, TreeNode parent, depth)
{
if (root == null) return;
// output 'depth' spaces.
// The indentation will help show the structure of the tree.
// output node value, and parent (if parent not null)
// Traverse the left node
ShowTree(root.left, root, depth+1);
// Traverse the right node
ShowTree(root.right, root, depth+1);
}
Call that function with ShowTree(tree, null, 0). The resulting output will show the structure of the tree, and you can determine if the tree is balanced. It's a useful thing to have when you're developing tree code because you can do an insert, for example, then call ShowTree to see if the insert worked as expected.
Update
The code's output is a little strange because your print statement results in a recursive call. So every node below the current node ends up getting printed multiple times.
I think you want to do this:
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
// now output output leftHeight or rightHeight, or both
return Math.max(leftHeight, rightHeight) + 1;
That way you won't get the multiple recursive calls that produce the strange output.
More info
The reason you're seeing those extra recursive calls is because you're calling getHeight(root.left) twice. Let's say your tree looks like this:
root
/
child
/
grandchild
So you call getHeight(root). Then:
getHeight(child) is called in your print statement
getHeight(grandchild) is called in your print statement
getHeight(null) is called in your print statement
getHeight(grandchild) prints 0
getHeight(null) is called twice (once for the left node and once for the right node) in the return statement
getHeight(grandchild) returns 1
getHeight(child) prints 1
getHeight(grandchild) is called in the return statement
getHeight(null) is called in your print statement
getHeight(grandchild) prints 0
getHeight(grandchild) returns 1
getHeight(null) (the right node) is called in the return statement
...
You see where the problem is? getHeight(grandchild) is called again! Every time your print statement calls getHeight, it has to walk every descendant node. So the height of every node is output multiple times. The deeper the node is in the tree, the more often it will be output.
The change I suggested in my update above prevents that by ensuring that no node is visited more than once.
recently I've been trying to teach myself a bit of recursion to understand the process better. While I understand basic recursion techniques, I still struggle quite a bit with the idea of recursive backtracking. In order to help this, I've attempted to program a method that solves a sudoku solver when given a 2D array and and two ints, r and c, which are meant to represent the current column and row.
I have everything set up properly I believe, yet I can't quite figure out how to handle the "unraveling", or what happens after my initial method calls reach the eventual base case.
As of right now, when I run this method, it just returns a board that's empty, (unless there was previously a value there before, in which case it remains unchanged). I feel like the "board[r][c] = 0" that I have at the end of the method might have something to do with that.
The method "digitsValid" corresponds to a method that checks to make sure the current location on the board is a valid move within the row, column, and 3x3 subgrid.
Any help would be much appreciated.
private boolean sudokuSolver(int[][] board, int r, int c) {
if(c > 8) {
c = 0;
r = r + 1;
}
if(r > 8) {
return true;
}
if(board[r][c] != 0) {
sudokuSolver(board, r, c + 1);
} else {
for(int i = 1; i <= 9; i++) {
if(digitsValid(board, r, c)) {
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) {
return true;
}
}
}
}
board[r][c] = 0;
return false;
}
I think your original assessment is correct. Recursive methods sound confusing but think of them like this:
public class RecursiveTest{
public static void main(String[] args){
int x = 5;
recursiveMethod(x);
}
public static void recursiveMethod(int i){
System.out.println("Method just started for i = " + i);
if(i > 0)
recursiveMethod(i - 1);
System.out.println("Method just ended for i = " + i);
}
}
Yields the following output:
Method just started for i = 5
Method just started for i = 4
Method just started for i = 3
Method just started for i = 2
Method just started for i = 1
Method just started for i = 0
Method just ended for i = 0
Method just ended for i = 1
Method just ended for i = 2
Method just ended for i = 3
Method just ended for i = 4
Method just ended for i = 5
Explanation
A recursive method is not all that different from any other method. It executes some code, at some point calls a method, runs that method and then continues running the rest of the code and finishes where any other method would finish.
The only difference is that method call is a call to itself. This would work the same as if you had copy-pasted that same method 5 times and named it all something different and then "daisy chained" them together.
In the example above, the original value is 5, it prints out that it started the for i=5, then ran the same method with the value of 4. Printed that, then ran 3 etc. Once it reached the final value where i = 0 the if statement failed and therefore it stopped the recursive calls. The method we are currently in (i = 0) finishes by writing Method just ended for i = 0 then it returns to the calling method when i = 1 and back tracks the same way it went in.
Your Code
I'm not quite sure what you have going on here. Does your example work? I'd like to see the isValid() method, but the following code you have:
for(int i = 1; i <= 9; i++) { // Runs the following code 9 times.
if(digitsValid(board, r, c)) { // if true once, true every time
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) { // this is a totally separate method
return true;
}
}
}
Your loop runs 9 times. The if statement following it never changes. The values within are not edited within the loop, so if it evaluates to true when i = 1 then it's going to evaluate to true on all 9 iterations of the for loop. This means the value at board[r][c] is going to end on 9.
From the looks of it, the only way this will ever return false, is if there is an invalid digit already stored in the array at the time of calling the method.
I am trying to configure out a method for checking conflicts between the head and all of the other nodes. At this point, I'm getting stuck in a loop. Any idea how to loop through the list, comparing head with head.next .next .next.next and so on?
EDIT: After adding a return false; after the conflictCheck(a,b.getNext()), there is no longer the loop problem but the output reflects this method NOT comparing each node with the head node.
EDIT X 2! : I believe I have the loop checking for conflicts working fine thanks to everyone who commented/answered. Now I have strange results in my program,where conflicts are being detected but nothing is being done about them. I've added my other important method that deals with these shenanigans. Also, my output is below. Is there any reason why Every node's column is moving to either 3, or staying at 1???
public static void playChess() {
System.out.println("Playing chess");
if (conflictCheck(head, head.getNext())) {
if (head.getColumn() == 8) {
queens.pop();
}
else if (!queens.isEmpty() && head.getColumn()!= 8) {
System.out.println("Adjusting head");
head.setColumn(head.getColumn()+1);
System.out.println("Head is now " + head.getRow() + ", " + head.getColumn());
playChess();
}
}
else if (queens.size() < 8) {
System.out.println("Stack isn't full yet");
queens.push(queens.size()+1,1);
queens.viewPieces();
playChess();
}
else {
success= true;
System.out.println("Success");
queens.viewPieces();
return;
}
}
public static boolean conflictCheck(QueenNode a, QueenNode b) {
//checks for conflicts between head and all other nodes in the stack
a= head;
while (b != null) {
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
conflictCheck(a,b.getNext());
}
else {
System.out.println("There is a conflict");
return true;
}
}
return false;
}
My output
Playing chess
Comparing 8 ,3 And 7 , 1
There is a conflict with 8,3 And 6,3
Success
The stack
8, 3
7, 1
6, 3
5, 1
4, 3
3, 1
2, 3
1, 1
End of stack
You're mixing the cycle with the recursive call.
If I understand you correctly, you would want something like:
public static boolean conflictCheck(QueenNode a, QueenNode b) {
//checks for conflicts between head and all other nodes in the stack
if (b == null){
return false;
}
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
return conflictCheck(a,b.getNext());
}
else {
System.out.println("There is a conflict");
return true;
}
}
I didn't run the code, so I'm hoping you get the picture, there's probably a syntax error or 4.
EDIT: As noted above, you also need a condition to end the recursion which I didnt include here - test if b is null sounds right.
The recursive call doesn't look right.
You would need to setup your initial a and b variable inside the block calling this recursive method, not inside the recursive method.
//...
a = nodes.head;
b = nodes.getNext();
if(conflictCheck(a, b)) {
//... there is a conflict
}
and then your method should look something like :
public static boolean conflictCheck(QueenNode a, QueenNode b) {
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
// there is no conflict here, check one step further into the list and return the result
return conflictCheck(a,b.getNext());
}
else {
// there is a conflict, stop here
System.out.println("There is a conflict");
return true;
}
}
HTH