Binary Search Tree traverse method, what makes it go up from lowest left child(leaf)? - binary-search-tree

I have a hard time understanding how the SearchTree "traverse in order method" goes up after it reaches the most left leaf. I UNDERSTAND that at first root becomes leftchild, than down 1 level leftchild again, again, until it becomes the lowest left leaf, which has no left child and no right child. OK. But how does it go level up after the root is the last leaf. What is the EXACT line of code that makes the traverse method go one level up from the lowest left child. Since for that node both root.leftchild and root.rightchild are null. This is magic to me.
public void inOrderTraverseTree(Node root) {
if (root != null) {
inOrderTraverseTree(root.leftChild);
System.out.println(root);
inOrderTraverseTree(root.rightChild);
}
}

This is because of the property of the recursive function which returns to it parent calling function after getting executed.
e.g.
20
/ \
10 30
this is a tree with its root as 20. Now walking through the inOrderTraverseTree code of yours:
1. call inOrderTraverseTree(20)
2. check for root being null, here 20 is not null.
3. call inOrderTraverseTree(10) {left of 20 is 10}
4. check for root being null, here 10 is not null.
5. call inOrderTraverseTree(null) {left of 10 is null}
6. check for root being null, here it is null.Hence exit out of "if",return to calling function,i.e step 4{root=10}
7. print root,i.e print 10.
8. call inOrderTraverseTree(null) {right of 10 is null}
9. check for root being null, here it is null.Hence exit out of "if",return to calling function,i.e step 3{root=20}.{complete execution for root=10 is completed}
10.print root,i.e print 20.
11.call inOrderTraverseTree(30){right of 20 is 30}
12.check for root being null, here 30 is not null.
13.call inOrderTraverseTree(null){left of 30 is null}
14. check for root being null, here it is null.Hence exit out of "if",return to calling function,i.e step 12{root=30}
15. print root,i.e print 30.
16. call inOrderTraverseTree(null) {right of 30 is null}
17. check for root being null, here it is null.Hence exit out of "if",return to calling function,i.e step 11{root=20}.{complete execution for root=30 is completed}
with this the complete execution of inOrderTraverseTree call with root 20 is also completed and the value printed is 10 (in step 7), 20 (in step 10), 30 (in step 15): 10 20 30.
Now coming to "code that makes the traverse method go one level up from the lowest left child" : you can see this happening in step 9. Where the leftmost child is returned to its parent calling function when the complete function cycle for leftmost child is fully executed. This is the main property of recursive function.

Imagine you've a stack, and every call to inOrderTraverseTree(Node root) being stored in the stack through some pointer(if you don't know what a pointer is, imagine there's a variable that represents a function call).
So, if inOrderTraverseTree(Node root) is called n times, the stack will have n pointers to the function.
What you're asking is, what'll happen after n calls? Well, the answer is, we return to the function that was previously called. This is done by removing the pointer at the top of the stack. Now, what we'll have at the top of the stack is the pointer to the previous function call.
In short, every time a recursive call is made, a pointer to the function is pushed to the stack. Once we reach the end of traversal, we start the popping elements from the stack one-by-one.
Since this operation involves push & pop only, this is the very reason a stack is being to store function calls.

Related

How do you see the full "called from" chain of function calls after an error?

Upon getting an error in the GAP command line interpreter, the chain of function calls that led to the error get's truncated, so I can see the start of the chain, which is the function I'd need to fix.
gap> MyAwesomeFunction(x,y);
Error, resulting list would be too large (length infinity) called from
ConstantTimeAccessList( enum ) at /path/to/gap/lib/coll.gi:506 called from
AsList( l ) at /path/to/gap/lib/list.gi:612 called from
AsPlist( l ) at /path/to/gap/lib/list.gi:673 called from
EnumeratorSorted( Enumerator( D ) ) at /path/to/gap/lib/domain.gi:231 called from
EnumeratorSorted( C ) at /path/to/gap/lib/coll.gi:862 called from
... at line 4 of *stdin*
you can 'quit;' to quit to outer loop, or
you can 'return;' to continue
brk>
How do I tell GAP to show me the full chain of functions here? What's behind that ...?
As per Alexander Konovalov's comment, the Where function is the key here. Entering Where(42) in the break look will show up to 42 functions in this "called from" chain.

How to count the number of cycles between two positions in LabVIEW on myRIO

I am very new to labview and recently I had been trying to make this sequence loop.
E.g.
myRio's starting position is ((x <0.05) && (y <=0.05) &&( z>0.9))
next while detecting myRio's position changes to ((x<0.2) && (y <= -0.9) &&( z<=0.3)) and then back again to the starting position, it will turn validate this as one correct cycle and change the counter from 0 to 1. and loop this whole sequence again.
Would really appreciate if you could highlight how can I do these kind of sequence looping. Thank you very much.
It sounds as if what you are trying to do is to count transitions between states. A great design pattern for anything involving transitions between states - which covers a large part of what people generally use LabVIEW for - is a state machine.
The link gives an explanation but essentially what you need is:
a While loop with a shift register
a case structure inside the loop whose case selector is wired to the left shift register terminal
some logic inside each case that decides what value to output to the right shift register terminal, i.e. what state to go to next.
In your case you could implement this with just two states:
State 1: Check position and see if we have reached the target position.
If so go to State 2
If not go to State 1 again
State 2: Check position and see if we have got back to the start position.
If so, increment the count and go to State 1
If not, go to State 2 again
However it would be slightly more elegant to use three states:
State 2: Check position and see if we have got back to the start position.
If so, go to State 3
If not, go to State 2 again
State 3: Increment the count and go to State 1.
You can use a second shift register for the counter: initialise it to 0, wire the left terminal across to the right one in States 1 and 2 (leaving the count unchanged) and increment it in State 3.
You can use an integer value or a string for the case selector, but the best practice is to use an enum which you save as a typedef. This allows you to reorder, rename, add or remove states later on without breaking existing code.

Understanding GNU Smalltalk Closure

The following piece of code is giving the error error: did not understand '#generality'
pqueue := SortedCollection new.
freqtable keysAndValuesDo: [:key :value |
(value notNil and: [value > 0]) ifTrue: [
|newvalue|
newvalue := Leaf new: key count: value.
pqueue add: newvalue.
]
].
[pqueue size > 1] whileTrue:[
|first second new_internal newcount|
first := pqueue removeFirst.
second := pqueue removeFirst.
first_count := first count.
second_count := second count.
newcount := first_count + second_count.
new_internal := Tree new: nl count: newcount left: first right: second.
pqueue add: new_internal.
].
The inconsistency is in the line pqueue add: new_internal. When I remove this line, the program compiles. I think the problem is related to the iteration block [pqueue size > 1] whileTrue: and pqueue add: new_internal.
Note: This is the algorithm to build the decoding tree based on huffman code.
error-message expanded
Object: $<10> error: did not understand #generality
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
Character(Object)>>doesNotUnderstand: #generality (SysExcept.st:1448)
SmallInteger(Number)>>retryDifferenceCoercing: (Number.st:357)
SmallInteger(Number)>>retryRelationalOp:coercing: (Number.st:295)
SmallInteger>><= (SmallInt.st:215)
Leaf>><= (hzip.st:30)
optimized [] in SortedCollection class>>defaultSortBlock (SortCollect.st:7)
SortedCollection>>insertionIndexFor:upTo: (SortCollect.st:702)
[] in SortedCollection>>merge (SortCollect.st:531)
SortedCollection(SequenceableCollection)>>reverseDo: (SeqCollect.st:958)
SortedCollection>>merge (SortCollect.st:528)
SortedCollection>>beConsistent (SortCollect.st:204)
SortedCollection(OrderedCollection)>>removeFirst (OrderColl.st:295)
optimized [] in UndefinedObject>>executeStatements (hzip.st:156)
BlockClosure>>whileTrue: (BlkClosure.st:328)
UndefinedObject>>executeStatements (hzip.st:154)
Object: $<10> error: did not understand #generality
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
Character(Object)>>doesNotUnderstand: #generality (SysExcept.st:1448)
SmallInteger(Number)>>retryDifferenceCoercing: (Number.st:357)
SmallInteger(Number)>>retryRelationalOp:coercing: (Number.st:295)
SmallInteger>><= (SmallInt.st:215)
Leaf>><= (hzip.st:30)
optimized [] in SortedCollection class>>defaultSortBlock (SortCollect.st:7)
SortedCollection>>insertionIndexFor:upTo: (SortCollect.st:702)
[] in SortedCollection>>merge (SortCollect.st:531)
SortedCollection(SequenceableCollection)>>reverseDo: (SeqCollect.st:958)
SortedCollection>>merge (SortCollect.st:528)
SortedCollection>>beConsistent (SortCollect.st:204)
SortedCollection(OrderedCollection)>>do: (OrderColl.st:64)
UndefinedObject>>executeStatements (hzip.st:164)
One learning we can take from this question is to acquire the habit of reading the stack trace trying to make sense of it. Let's focus in the last few messages:
1. Object: $<10> error: did not understand #generality
2. MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
3. Character(Object)>>doesNotUnderstand: #generality (SysExcept.st:1448)
4. SmallInteger(Number)>>retryDifferenceCoercing: (Number.st:357)
5. SmallInteger(Number)>>retryRelationalOp:coercing: (Number.st:295)
6. SmallInteger>><= (SmallInt.st:215)
7. Leaf>><= (hzip.st:30)
8. optimized [] in SortedCollection class>>defaultSortBlock (SortCollect.st:7)
Each of these lines represents the activation of a method. Every line represents a message and the sequence of messages goes upwards (as it happens in any Stack.) The full detail of every activation can be seen in the debugger. Here, however, we only are presented with the class >> #selector pair. There are several interesting facts we can identify from this summarized information:
In line 1 we get the actual error. In this case we got a MessageNotUnderstood exception. The receiver of the message was the Character $<10>, i.e., the linefeed character.
Lines 2 and 3 confirm that the not understood message was #generality.
Lines 4, 5 and 6 show the progression of messages that ended up sending #generality to the wrong object (linefeed). While 4 and 5 might look obscure for the non-experienced Smalltalker, line 6 has the key information: some SmallInteger received the <= message. This message would fail because the argument wasn't the appropriate one. From the information we already got we know that the argument was the linefeed character.
Line 7 shows that SmallInteger >> #<= came from the way the same selector #<= is implemented in Leaf. It tells us that a Leaf delegates #<= to some Integer known to it.
Line 8 says why we are dealing with the comparison selector #<=. The reason is that we are sorting some collection.
So, we are trying to sort a collection of Leaf objects which rely on some integers for their comparison and somehow one of those "integers" wasn't a Number but the Character linefeed.
If we take a look at the Smalltalk code with this information in mind we see:
The SortedCollection is pqueue and the Leaf objects are the items being added to it.
The invariant property of a SortedCollection is that it always has its elements ordered by a given criterion. Consequently, every time we add: an element to it, the element will be inserted in the correct position. Hence the comparison message #<=.
Now let's look for #add: in the code. Besides of the one above, there is another below:
new_internal := Tree new: nl count: newcount left: first right: second.
pqueue add: new_internal.
This one is interesting because is where the error happens. Note however that we are not adding a Leaf here but a Tree. But wait, it might be that a Tree and a Leaf belong to the same hierarchy. In fact, both Tree and Leaf represent nodes in an acyclic graph. Moreover, the code confirms this idea when it reads:
Leaf new: key count: value.
...
Tree new: nl count: newcount left: first right: second.
See? Both Leaf and Tree have some key (the argument of new:) and some count. In addition, Trees have left and right branches, which Leafs not (of course!)
So, in principle, it would be ok to add instances of Tree to our pqueue collection. This cannot be what causes the error.
Now, if we look closer to the way the Tree is created we can see a suspicious argument nl. This is interesting because of two reasons: (i) the variable nl is not defined in the part of the code we were given and (ii) the variable nl is the key that will be used by the Tree to respond to the #<= message. Therefore, nl must be the linefeed character $<10>. Which makes a lot of sense because nl is an abbreviation of newline and in the Linux world newlines are linefeeds.
Conclusion: The problem seems to be caused by the wrong argument nl used for the Tree's key.

how can i use wexitstatus to get the value more than 255

I can just speak a little English so I hope you can understand what I said.
I fork a child process , then I do ADD in child process. EX: 56+48=104
If the value lower than 255 , I can use "wexitstatus(status)" to get the answer.
But if the value higher than 256, it would be wrong !
How can I do?
If the program returns an exit code > 255, the program is simply wrong and needs to be fixed. That's against Unix standard. If you're not using standard Unix, you're probably going to need specialist help from within your organisation contacts.
From manpage for wait():
WEXITSTATUS(stat_val)
If the value of WIFEXITED(stat_val) is non-zero, this macro evaluates to the low-order 8 bits of the status argument that the child process passed to _exit() or exit(), or the value the child process returned from main().
It's limited to 8-bits, which means 1 byte, which means the int from WEXITSTATUS can only range from 0-255. In fact, any Unix program will only ever return a max of 255.
Additionally, many OS's/programs reserve > 127 for system designated codes, so you shouldn't even use anything above that.
If you need more return codes than 126 (since 0 is no error), consider writing it to STDOUT and hooking that.

CS193P, runProgram and Assignment 2

I'm working on assignment 2 of CS193P - Stanford's IOS programming course. One thing I was wondering about is how the calculatorBrain is supposed to be able to accept and run a stored program, a program being an array or stack of operands and operations.
So let's say we want to perform the following calculation: 2, 3, 4, +, *
If you typed this into the calulator, the following would happen:
2 3 4 get pushed onto the stack one at a time, and runProgram called for each one, which simply pops the number off the stack and returns it's value which gets pushed onto the stack.
You press +, and runProgram pops this and sees it has to add the top 2 items which it does and pushes the result onto the stack which now contains 2, 7. You press * and the stack now contains 14.
But I can't see how you can pass an array containing (2, 3, 4, +, *) to the brain (the instructor says later you can just pass a program to the runProgram class method and get the result, without having to instantiate a brain object), as runProgram would first try to execute the top operand i.e. * and to do this it would take the next two objects off the stack and try to multiply them and to push the result back onto the stack. These 2 objects are "+" and "4" which won't work.
Now the instructor has been doing this a lot longer than I have, as I assume that I'm missing somethings, but I'm not sure what.
Any ideas?
If you look at this as passing "2,3,4,+,*" to the "brain", you need to be thinking in the context of the stack processor.
The arguments are evaluated in the order in which they are encountered in the array. But, don't confuse the array for the stack, they are different objects. The stack is internal to the calculator routine and the array of input is external to the routine. Since I'm not taking that particular class at whatever school you're in, I can't speak to the particulars of the language in use, but basically, think of the array "2,3,4,+,*" as input to the keyboard of the calculator. However, the calculator is a very simple machine and only processes one key press at a time.
Thus, when you process the array, you're basically passing each element of the array to the calculator for processing and the calculator is then deciding whether to push to the stack or execute the operator. These elements are passed in order, so the calculator receives: 2 followed by 3, followed by 4, followed by '+', followed by '*'.
It looks like you're trying to think of the problem in terms of the array being passed in to the calculator as the stack, and that's not what you want to do here.
I hope this is clear.
OK - the answer is that the way runProgram gets the next item off the stack is by recursively calling a popOperandOffStack (pOOS) method.
So when it gets passed a program consisting of 2 3 4 + *, it starts by popping * off the stack. It then has to pop the next two operands off the stack. So it calls pOOS, which firstly returns a '+', so it then calls pOOS again (twice) which gets '4' & '3' respectively, which are added to get 7 which is pushed back onto the stack (which now contains 2 7) and also returned as the result of calling pOOS. So when it called pOOS for the first operand of the '*' operation it didn't get '+', it actually got '7'. The second call to pOOS (for the second operand of the *) gets '2' which it then happily multiplies to get 14.
I did try looking up recursion in my IT dictionary, but it just said 'See recursion'.
#steve Ives, I think you nailed the answer with this last comment. Having gone through this assignment a few weeks back (also on my own), I found this site to be helpful understanding the reverse polish calculator, it basically emulates one. But as you are thinking recursion, your brain can go into overload mode. Hope this helps validating some of your scenario testing...Good luck.
HP12C Emulator