Why is this code correct while it should clearly run into an infinite loop? - binary-heap

I have been having a problem with this code for a while. The placement of recursive call of the function does not seem right.
i tried running the code and yes it does run into a infinite loop.
// I DEFINE HEAP STRUCTURE AS :
struct heap_array
{
int *array; // heap implementation using arrays(note : heap is atype of a tree).
int capacity; // how much the heap can hold.
int size; //how much size is currently occupied.
void MaxHeapify(struct heap_array *h,int loc) // note : loc is the location of element to be PERCOLATED DOWN.
{
int left,right,max_loc=loc;
left=left_loc_child(h,loc);
right=right_loc_child(h,loc);
if(left !=-1 && h->array[left]>h->array[loc])
{
max_loc=left;
}
if(right!=-1 && h->array[right]>h->array[max_loc])
{
max_loc=right;
}
if(max_loc!=loc) //i.e. if changes were made:
{
//swap the element at max_loc and loc
int temp=h->array[max_loc];
h->array[max_loc]=h->array[loc];
h->array[loc]=temp;
}
MaxHeapify(h,max_loc); // <-- i feel that this recursive call is misplaced. I have seen the exact same code in almost all the online videos and some books i referred to. ALSO I THINK THAT THE CALL SHOULD BE MADE WITHIN THE SCOPE OF condition if(max_loc!=loc).
//if no changes made, end the func right there.
}

In your current implementation, it looks like you don't have a base case for recursion to stop.
Remember that you need a base case in a recursive function (in this case, your MaxHeapify function), and it doesn't look like there is one.
Here is an example of MaxHeap which may be resourceful to look at
// A recursive function to max heapify the given
// subtree. This function assumes that the left and
// right subtrees are already heapified, we only need
// to fix the root.
private void maxHeapify(int pos)
{
if (isLeaf(pos))
return;
if (Heap[pos] < Heap[leftChild(pos)] ||
Heap[pos] < Heap[rightChild(pos)]) {
if (Heap[leftChild(pos)] > Heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
maxHeapify(leftChild(pos));
}
else {
swap(pos, rightChild(pos));
maxHeapify(rightChild(pos));
}
}
}
Here, you can see the basecase of:
if (isLeaf(pos))
return;
You need to add a base case to your recursive function.

Related

protothread jump a thread to the beginning in the external main function

I have a protothread set up and blocking ...
static int mythread(struct pt *pt){
static int k;
PT_BEGIN(pt)
while(1){
PT_WAIT_UNTIL(pt, eventA == 1); // blocked at lineA
for(k=0;k<100;k++){
//do something
PT_YIELD(pt); //blocked at lineB
}
PT_WAIT_UNTIL(pt, eventB == 1); //block at lineC
}
PT_END(pt)
}
After a while, mythread can be blocked at "lineA", "lineB", or "lineC".
How could an external function, like main() reset mythread to be blocked at the beginning "lineA" again.
By running the macro PT_RESTART(&pt_mythread)? The compiler doesn't like it. Because my main() function isn't inside PT_BEGIN, PT_END block, so the return inside that macro is bad, bad.
Or running PT_INIT(&pt_mythread) again? Any suggestions?
Yes, calling PT_INIT from outside the protothread will restart it. If you look at the source for PT_RESTART:
#define PT_RESTART(pt) \
do { \
PT_INIT(pt); \
return PT_WAITING; \
} while(0)
This is exactly what it does, but then also returns (like a yield) out of the thread. As you say it's designed to be called from inside the protothread.
The protothread struct is basically just a number representing where it was in the thread:
struct pt {
lc_t lc; // where lc_t is an unsigned short;
};
So the only thing we need to do is reset that number to zero, which is exactly what PT_INIT does.

Recursive code for maximum height of a binary tree

I came across a recursive code for calculating the maximum height of a binary tree-
int maxDepth(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth+1);
else return(rDepth+1);
}
}
I'm tried to write the code in another way-
int maxDepth(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = 1+maxDepth(node->left); //notice the change
int rDepth = 1+maxDepth(node->right); //notice the change
/* use the larger one */
if (lDepth > rDepth)
return(lDepth);
else return(rDepth);
}
}
I'm confused whether both versions will work similarly or is there a bug in the second implementation.
I tried out few cases, for which both functions returned same results.
Arithmetically they are the same, it doesn't matter when you add the 1 to the answer because no other arithmetic transformations are being done to the value which gets returned. Technically yours is slightly less efficient because you do two additions, then throw away the smaller of the two values which wastes the work done on that one. In reality I doubt you'd ever notice the difference if you did timings.
These two C functions will behave identically. All you have done in your rewrite of the function maxDepth() is to add 1 to the variables lDepth and rDepth. However, you effectively undo that change by subtracting 1 from these variables in your return value:
int lDepth = 1+maxDepth(node->left); // you added one to lDepth
int rDepth = 1+maxDepth(node->right); // you added one to rDepth
/* use the larger one */
if (lDepth > rDepth)
return(lDepth); // but you subtract one here
else return(rDepth); // and you also subtract one here

Are recursive functions a special case of higher order functions

Wikipedia states:
In mathematics and computer science, a higher-order function (also
functional form, functional or functor) is a function that does at
least one of the following:
takes one or more functions as an input
outputs a function
Also,
A recursive function is a function that calls itself during its
execution.
Does this mean a recursive function could be classified as a very special case of higher-order function?
Please refer this case:
int foo(int i)
{
if(i>10)
{
return 10;
}
cout<<i;
return foo(++i);
}
I do not want opinions. Please state your answer with specific premises.
Imagine your Algol dialect didn't support recursion but supported higher order functions. Could we implement your example still? Sure you can!
int foo_aux(int i, Func cont)
{
if( i>10 ) {
return 10;
} else {
cout<<i; // side effect bad!
return cont(i+1, cont); // no recursion
}
}
int foo(int i)
{
return foo_aux(i, [] (int i, Func cont) -> int { return foo_aux(i,cont) });
}
Imagine you try to do the same but your language doesn't support higher order functions nor recursion. Is it possible to emulate it? Everything is possible:
std::stack<int> args; // integers can be castable pointers or numbers!
int cont = 2;
while( cont ) {
if( cont == 2 ) { // main
args.push(1)
cont=1; // continuation == foo_aux
} else if ( cont == 1 ) { // foo_aux
int tmp = args.pop();
if( tmp > 10 ) {
args.push(10);
cont=0; // continuation == return/exit
} else {
cout << tmp;
args.push(tmp+1);
// not setting cont == recursion
}
}
}
// do something with the result
return args.pop();
This is a way of doing recursion like in your initial example. Perhaps you could make a preprocessor (macro) to do the conversion from something fancy like your example to become this for compilation. If you wanted to pass the function as an argument you just push the number and your receiving function would need to set f.
std::stack<int> args; // integers can be castable pointers or numbers!
args.push(2) // bootstrap
int cont = 0;
while( cont = args.pop() ) {
if( cont == 2 ) { // main / foo
args.push(1) // push argument
args.push(1) // push function
} else if ( cont == 1 ) { // foo_aux
int tmp = args.pop();
if( tmp > 10 ) {
args.push(10); // push result
args.push(0); // push exit as continuation
} else {
cout << tmp;
args.push(tmp+1); // push argument
args.push(1); // push self as argument
}
}
}
// do something with the result
return args.pop();
This does not support so called upwards funarg since then you need to have another structure for closed over variable no longer in scope.
So is recursion a special case of higher order functions? Since functions can be emulated using a function index it's possible to implement functions, recursion and higher order functions at the same time from a compiler view point. This only means functions can be modeled the same way. It's perfectly possible to make a compiler that uses assembly functions that do not support higher order functions but support recursion and it's possible to make a language without recursion that support higher order functions that will enable a way of doing recursion with something like a Y combinator. Other than that they are completely different things.
No. "Outputting" a function in this context means returning a function, not returning the result of calling a function. That is, the return value is itself callable. Recursive functions in general do not necessarily do this. For example:
def factorial(n: int) -> int:
if n == 0:
return 1
else:
return n*factorial(n-1)
This code returns an integer. You cannot call an integer, so it is not a higher-order function.
No.
outputs a function means functions can be used as return value of a function, like this (code in Lua):
function foo()
return function(a,b) return a + b end
end
In your example of recursive function, the return value is the result of the expresion foo(++i), not the function foo itself.
A higher order function is a function that can take conditions or functions as arguement. And it can optionally output a function as the return statement .
therefore ,recursive functions are not all higher level functions.
Also, higher level functions are not all recursive, because some just use conditions as arguements .

How does fork and pipe work in a unix process system?

I'm trying to study for an exam and I'm just not able to figure out a simple fork program.
I have this piece of code and have to add code to it In order for the parent process to send through a PIPE the value n to the child. The child should double the value, not print anything and return it to the parent.
Then the parent should print it on the screen.
int main() {
int n=1;
if(fork() == 0) {
}
printf(ā€œ%d\nā€, n);
return 1;
}
I don't really know how PIPEs work and how to use them. Can anyone help me?
pid_t cp;
int fi[2],st;
int n;
if(pipe(fi)==-1) {perror("pipe error");exit(0);}
if((cp=fork())==-1) {perror("fork"); exit(0);}
else if(cp==0)
{
sleep(2);
close(fi[1]);
read(fi[0],&n,2);
n*=2;
close(fi[0]);
exit(n);
}
else
{
close(fi[0]);
write(fi[1],n,2);
close(fi[1]);
waitpid(cp,&st,0);
printf("%d",st);
exit(0);
}}
The working of pipes is very simple. A PIPE contains two ends, 1 for reading and another for writing. You have to close the appropriate end while reading or writing. After that you use it as a regular file with read() and write() functions. Forgive me for my formatting, I'm typing on a mobile.

How to capture output of execvp

I'm developing a program which executes a program using execvp. It needs to capture the results of the child process and parse them in the main process. It seems there is a way, using named pipes, and duping. I'm trying to hunt down a good example of this, but so far no luck. If anyone has any pointers, links and/or suggestions about this, I'd greatly appreciate it.
You don't need named pipes; unnamed pipes work just fine. Actually, often you can just use popen instead of doing the pipe/fork/dup/exec yourself. popen works like this (though your libc's implementation likely has more error checking):
FILE *popen(const char *command, const char *type) {
int fds[2];
const char *argv[4] = {"/bin/sh", "-c", command};
pipe(fds);
if (fork() == 0) {
close(fds[0]);
dup2(type[0] == 'r' ? 0 : 1, fds[1]);
close(fds[1]);
execvp(argv[0], argv);
exit(-1);
}
close(fds[1]);
return fdopen(fds[0], type);
}
This creates an unnamed pipe, and forks. In the child, it reattaches stdout (or stdin) to one end of the pipe, then execs the child. The parent can simply read (or write) from the other end of the pipe.
Can't you just use popen()?
Here is a simple example that demonstrates the use of popen to achieve your goal. Just put something more interesting than "echo" as the command :)
#include <stdio.h>
int main()
{
char buf[100];
int i = 0;
FILE *p = popen("echo \"Test\"","r");
if (p != NULL )
{
while (!feof(p) && (i < 99) )
{
fread(&buf[i++],1,1,p);
}
buf[i] = 0;
printf("%s",buf);
pclose(p);
return 0;
}
else
{
return -1;
}
}

Resources