I'm new to golang and confused by the following,
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func test() []*TreeNode {
return []*TreeNode{}
}
func test1() []*TreeNode {
return []*TreeNode{nil}
}
I'm trying to write a recursion func on TreeNode, however, if I used the test style to represent the leaf node, I will get an empty TreeNode slice from the caller func.
If I use the test1 to represent the leaf node, then the behaviour is what I want.
I feel that for the test1, it's giving me a point to an empty TreeNode, however, the test code, is giving me a point to nil... I'm not sure if I'm getting this right or not. Can you please point me the correct terms or concepts to dig, it will be great.
In addition, if you can let me know more about the underline logic, it would be great.
Thanks in advance.
This returns an empty slice:
return []*TreeNode{}
This returns a slice containing one element, and that element is a nil pointer:
return []*TreeNode{nil}
None of these give you a TreeNode though. The second one gives you a TreeNode pointer that is nil. How you interpret these depends on the rest of the code, but I doubt either is really what you want, since none can have the val field.
I've written a basic Node struct in D, designed to be used as a part of a tree-like structure. The code is as follows:
import std.algorithm: min;
alias Number = size_t;
struct Node {
private {
Node* left, right, parent;
Number val;
}
this(Number n) {val = n;}
this(ref Node u, ref Node v) {
this.left = &u;
this.right = &v;
val = min(u.val, v.val);
u.parent = &this;
v.parent = &this;
}
}
Now, I wrote a simple function which is supposed to give me a Node (meaning a whole tree) with the argument array providing the leaves, as follows.
alias Number = size_t;
Node make_tree (Number[] nums) {
if (nums.length == 1) {
return Node(nums[0]);
} else {
Number half = nums.length/2;
return Node(make_tree(nums[0..half]), make_tree(nums[half..$]));
}
}
Now, when I try to run it through dmd, I get the following error message:
Error: constructor Node.this (ulong n) is not callable using argument types (Node, Node)
This makes no sense to me - why is it trying to call a one-argument constructor when given two arguments?
The problem has nothing to do with constructors. It has to do with passing by ref. The constructor that you're trying to use
this(ref Node u, ref Node v) {...}
accepts its arguments by ref. That means that they must be lvalues (i.e. something that can be on the left-hand side of an assignment). But you're passing it the result of a function call which does not return by ref (so, it's returning a temporary, which is an rvalue - something that can go on the right-hand side of an assignment but not the left). So, what you're trying to do is illegal. Now, the error message isn't great, since it's giving an error with regards to the first constructor rather than the second, but regardless, you don't have a constructor which matches what you're trying to do. At the moment, I can think of 3 options:
Get rid of the ref on the constructor's parameters. If you're only going to be passing it the result of a function call like you're doing now, having it accept ref doesn't help you anyway. The returned value will be moved into the function's parameter, so no copy will take place, and ref isn't buying you anything. Certainly, assigning the return values to local variables so that you can pass them to the constructor as it's currently written would lose you something, since then you'd be making unnecessary copies.
Overload the constructor so that it accepts either ref or non-ref. e.g.
void foo(ref Bar b) { ... }
void foo(Bar b) { foo(b); } //this calls the other foo
In general, this works reasonably well when you have one parameter, but it would be a bit annoying here, because you end up with an exponential explosion of function signatures as you add parameters. So, for your constructor, you'd end up with
this(ref Node u, ref Node v) {...}
this(ref Node u, Node v) { this(u, v); }
this(Node u, ref Node v) { this(u, v); }
this(Node u, Node v) { this(u, v); }
And if you added a 3rd parameter, you'd end up with eight overloads. So, it really doesn't scale beyond a single parameter.
Templatize the constructor and use auto ref. This essentially does what #2 does, but you only have to write the function once:
this()(auto ref Node u, auto ref Node v) {...}
This will then generate a copy of the function to match the arguments given (up to 4 different versions of it with the full function body in each rather than 3 of them just forwarding to the 4th one), but you only had to write it once. And in this particular case, it's probably reasonable to templatize the function, since you're dealing with a struct. If Node were a class though, it might not make sense, since templated functions can't be virtual.
So, if you really want to be able to pass by ref, then in this particular case, you should probably go with #3 and templatize the constructor and use auto ref. However, personally, I wouldn't bother. I'd just go with #1. Your usage pattern here wouldn't get anything from auto ref, since you're always passing it two rvalues, and your Node struct isn't exactly huge anyway, so while you obviously wouldn't want to copy it if you don't need to, copying an lvalue to pass it to the constructor probably wouldn't matter much unless you were doing it a lot. But again, you're only going to end up with a copy if you pass it an lvalue, since an rvalue can be moved rather than copied, and you're only passing it rvalues right now (at least with the code shown here). So, unless you're doing something different with that constructor which would involve passing it lvalues, there's no point in worrying about lvalues - or about the Nodes being copied when they're returned from a function and passed into the constructor (since that's a move, not a copy). As such, just removing the refs would be the best choice.
I was trying to understand program of recursion
Anyone Please explain working of size(). how it is returning no. of nodes recursively.
int size(struct tree *root)
{
if (root==NULL)
return 0;
else
{
return (size(root->left)+size(root->right)+1);
}
}:
In this program what does size(root->left),size(root->right) will return??
As in factorial program
function factorial (x)
{
return (x * factorial(x-1) ) ;
}
In this factorial program it will return 4*3*2*1.If we calculate for factorial(4).
In the above tree program what should return value of that node.Why it is returning no. of nodes?not the value of that node.
Please Explain.
The size function is calculating the number of nodes in the tree (completely independent of the values of the nodes). The recursion works because if the tree root is NULL it returns 0 (base case). If the root is not NULL, it has a left and right child (both of which are trees). So the total size will be size of left subtree (i.e. size(root->left)) + size of right subtree (i.e .size(root->right)) + size of root node (i.e. 1).
your program never is reading the value of node. instead is counting no. of nodes.
it returns 0 on reaching null. it adds 1 when all the nodes in right and left subtree are counted and returns the final sum.
Sorry if this is a very basic question, I am just trying to learn recursion.
The below code can reverse a linked list.
I understand the logic until line 3, but I am confused when line 4 will be called (n.next=prev) since the function gets called again before executing this line.
Can someone let me know the flow of this recursion?
void reverse(node n, node prev) {
if (n == null) { newroot = prev; return; }
reverse(n.next, n);
n.next = prev;
}
As soon as n hits null and reverse function return it will backtrack from there to it's calling function all the way to it's first calling function.
UPDATE: See the comments below for a more complete explanation.
As I know, a recursive function is a function which calls it self, and it has the characteristic of having a base case. This is a function for pre-order traversal of a binary tree. Is this a recursive function? Absence of the base case confuses me.
void pre_order(struct node* current){ // preorder traversal
printf("%d\n",current->data);
if(current->left != NULL){
pre_order(current->left);
}
if(current->right !=NULL){
pre_order(current->right);
}
}
Since it calls itself it is a recursive function. That's how simple it is. There's also a base case here, but it's a little hidden perhaps. When we get to a leaf in this binary tree both left and right childs will be equal to null and therefore no more recursive calls will happen. That's our base case that's a little hidden.