Implementation of recursive Mergesort - c

I made a recursive merge sort code,but it is not working,can anyone tell me where am I going wrong in the code.
void mergesort(int A[],int start,int end)
{
int B[(end-start)/2],C[(end-start)/2],i,j,k,flag=0;
if(start==end)
return;
else
{
mergesort(A,start,(start+end)/2);
mergesort(A,(start+end)/2+1,end);
}
for(i=start;i<(start+end)/2;i++)
B[i]=A[i];
for(i=(start+end)/2+1;i<end;i++)
C[i]=A[i];
for(i=start,j=start,k=(start+end)/2+1;i<end;i++)
{
if(j==(start+end)/2)
{
while(k!=end)
A[i]=C[k++];
flag=1;
}
if(k==end)
{
while(j!=(start+end)/2)
A[i]=B[j++];
flag=1;
}
if(flag)
break;
if(A[j]>C[k])
A[i]=C[k++];
else
A[i]=B[j++];
}
return;
}
In the first part of the code i am trying to divide the array into 2 sub arrays and if i am left with only one element, I start merging and reach the top to obtain the sorted array.

One of the end points in your recursive calls is wrong. You need to decide if end is included in the sub-array or one past the end of the array. The code appears to want to exclude end, however your recursive calls look like this:
mergesort(A,start,(start+end)/2); // should be (start+end)/2+1 if end is excluded
mergesort(A,(start+end)/2+1,end);

A killer problem is that the loop
for(i=(start+end)/2+1;i<end;i++)
C[i]=A[i];
immediately writes beyond the array. All bets are off, but in any case C doesn't contain what you expect it to.

Related

Why does function not work when I add a function in it?

I am new at recursive functions.
int display(int num) {
if(num) {
display(num-1);
}
else {
return 0;
}
printf("\t%d", num);
}
When I run display(5), i can get "1 2 3 4 5" output as i want.
BUT:
When I add another function in this code and make some changes on the display() function and run the display(5) command it gives no output.. Here is the other code:
int bunnyEars2(int line) {
if(line == 0) {
return 0;
}
if(line % 2 == 1) {
return 2 + bunnyEars2(line-1);
}
else {
return 3 + bunnyEars2(line-1);
}
}
int display(int n) {
if(bunnyEars2(n)) {
display(bunnyEars2(n-1));
}
else {
return 0;
}
printf("\n%d", bunnyEars2(n));
}
I want to take bunnyEars2(1), bunnyEars2(2), bunnyEars2(3), bunnyEars2(4), bunnyEars2(5) outputs from display(5) command. But it gives no output. Can you help me out with this?
When you call display(5) it calls display(bunnyEars2(5)) which is display(12) => infinite loop
display(n) calls display(bunnyEars2(n-1)) and for every n>=2, bunnyEars2(n-1) > n so that you will get an infinite loop.
Other people have already given the reason for why this code is causing issues so I'll go into how to potentially look the causes of issues like this in the future.
When writing a recursive function, It is important to identify the various cases for your function. Each recursive function will have a set of cases which cause the function to call itself (recursive cases) and a set of functions in which the function will not call itself (base cases). In the case of the display function given in the first example. The recursive case is -- num has a non zero value, and the base case is -- num has a value of 0. A recursive function will only cease recursing if a function call hits a base case causing the recursive function calls to resolve rising up the call stack. Under any circumstance, any call to a recursive function does not lead a call of the function resulting in the execution of the base case, the call to the function will not resolve resulting in infinite recursion.
This infinite recursion is occurring in your second version of the display function. Look closely at the recursive case of your second display function.
if(bunnyEars2(n)){
display(bunnyEars2(n-1));
}
How would the value of bunnyEars2(n-1) compare to the value of n? Examine whether this recursive case will result in a calling of the function that executes a base case.
If you have access to a debugger and know how to use it, try stepping through the function and see what path it takes through the code. If you do not have access to a debugger, get some paper and a pencil and walk through the execution of your function by hand. This should give you a better idea about what your code is doing and how a problem might arise.

Stack implemented as an array defaulting first value to 0 in C

I have an assignment where I am supposed to use this very very simple (or so I thought) stack that my teacher wrote in C, just using an array. From this, I have to implement reverse polish notation from a text file.
In order for me to implement this, I am using a stack, pushing values on until I hit an operation. I then do the operation and push the result back onto the stack until the user hits p to print the value.
The problem is, for some reason, my professor's implementation of the stack array defaults the first (index 0) value to 0. Printing the stack without pushing anything onto it should result in null but it appears the output is 0.
Here is my professor's implementation of the stack:
#define STK_MAX 1024
#define ELE int
ELE _stk[STK_MAX];
int _top = 0;
void stk_error(char *msg)
{
fprintf(stderr, "Error: %s\n", msg);
exit(-1);
}
int stk_is_full()
{
return _top >= STK_MAX;
}
int stk_is_empty()
{
return _top == 0;
}
void stk_push(ELE v)
{
if ( stk_is_full() )
stk_error("Push on full stack");
_stk[_top++] = v;
}
ELE stk_pop()
{
if ( stk_is_empty() )
stk_error("pop on empty stack");
return _stk[--_top];
}
void print()
{
for(int i = 0; i <= _top; ++i)
printf("%d ", _stk[i]);
printf("\n");
}
I realize that the print statement will print a value that has not been pushed yet, but the problem is, is that when I don't print it, it still ends up there and it ends up screwing up my rpn calculator. Here is what happens when I do this:
// input
stk_push(2);
print();
stk_push(4);
print();
// output
2 0
2 4 0
How do I get rid of the 0 value that is affecting my calculator? Doing stk_pop() after the pushing the first value onto the stack didn't seem to work, and checking that top == 0, then directly inserting that element before incrementing _top didn't work.
When you are printing, loop from 0 to (_top - 1), since your top most element is actually at _top - 1. Hint : Look at your pop/push method.
void print()
{
for(int i = 0; i < _top; ++i)
printf("%d ", _stk[i]);
printf("\n");
}
"The problem is, is that the rpn calculator relies on the TOS being accurate. When I do pop() though, it will pop 0 and not the real TOS."
Sounds like a problem with your calculator implementation. You assumed the top of the stack would be null, but that's not the case for your professors stack implementation. Simply a invalid assumption.
Instead he's provided a stk_is_empty() method to help determine when you've pop everything.
If you need to pop all elements, you'll need to break on the condition of stk_is_empty().
stk_push(2);
stk_push(4);
while( stk_is_empty() == false)
{
stk_pop();
}
Of course in reality you'd be setting the pop return to a variable and doing something with it. The key point is leveraging stk_is_empty().
I haven't written C++ in few years so hopefully I didn't make a minor syntax error.

Binary Search in C using recursion

The program crashes in finding a number which is not available in the array.The code works perfectly when i search for elements which are available in the array.Help much appreciated.
#include<stdio.h>
int binarySearch(int a[],int s,int key)
{
int middle;
if(s!=1)
middle=s/2;
if(a[middle]==key)
return 1;
else if(key<a[middle])
binarySearch(a,middle,key);
else if(key>a[middle])
binarySearch(&a[middle],middle,key);
else
return 0;
}
void main()
{
int i;
int a[]={1,2,3,4,6,9,10,11};
for (i =0;i<8;i++)
printf("%i ",a[i]);
if(binarySearch(a,8,5))
printf("\nFound");
else
printf("\nNot Found");
}
Change
if(s!=1)
middle=s/2;
if(a[middle]==key)
return 1;
else if(key<a[middle])binarySearch(a,middle,key);
else if(key>a[middle])binarySearch(&a[middle],middle,key);
to
if (s != 1){
middle = s / 2;
if (a[middle] == key)
return 1;
else if (key<a[middle])binarySearch(a, middle, key);
else if (key>a[middle])binarySearch(&a[middle], middle, key);
}
The variable middle is initialized only if s!=1.
I have run this code and got the value Not Found for input 5.
If you are running your code in release mode, try building it in debug mode and run step by step you will see what happens when middle is used directly without assigning it a specific value. This is harmful.
Hope this helps.
The code if(key<a[middle])binarySearch(a,middle,key); does not return anything.
Try if(key<a[middle]) return binarySearch(a,middle,key);
This may still not work as you intend it to, but at least you will get past the major, immediately visible, cause of runaway recursion.
Because there is no case if the s == 1. "Middle" is not initialized and a[middle] is potential crash, or it will just go infinite.
A few notes:
Every branch of a recursive function should return something. You'll need to modify your recursive calls to return the call
Change
binarySearch(a, middle, key)
to
return binarySearch(a, middle, key)
Also, make sure middle is computed properly. You don't properly initialize it in the situation where s == 1. You'll want this to start at 0 most likely.

Build a binary-heap from an array, which method is more efficient and why

I am learning about heaps and i have found two ways of building them from a given array:
I am trying to build up a MAX Heap.
1.Top to down approach
Here i just check for every element if it is at the correct position or not. By using a method called restoreUp, in which every key is compared to its parent key , and if the parent key is smaller than the parent key is moved down.This procedue continues till the parent key is greater.I check it for every key starting at index position 2.
My Code is:
void restoreUp(int arr[],int i)
{
int k=arr[i];
int par=i/2;
while(arr[par]<k)
{
arr[i]=arr[par];
i=par;
par=i/2;
}
arr[i]=k;
}
void buildheap1(int arr[],int size)
{
int i;
for(i=2;i<=size;i++)
restoreUp(arr,i);
}
Bottom up approach
Here i start from the first non leaf node present at index floor(size/2), and call a method restoreDown until node number 1.I compare a key with both its left and right child and then the greater child is moved up.If both children are greater than the key then move the larger of the 2 children up.This procedure stops when both children are smaller than the key.
My Code is:
void restoreDown(int arr[],int i,int size)
{
int left=2*i;
int right=2*i+1;
int num=arr[i];
while(right<=size)
{
if(num>arr[left] && num>arr[right])
{
arr[i]=num;
return;
}
else if(arr[left]>arr[right])
{
arr[i]=arr[left];
i=left;
}
else
{
arr[i]=arr[right];
i=right;
}
left=2*i;
right=2*i+1;
}
if(left==size && arr[left]>num)
{
arr[i]=arr[left];
i=left;
}
arr[i]=num;
}
void buildheap2(int arr[],int size)
{
int i;
for(i=size/2;i>=1;i--)
restoreDown(arr,i,size);
}
Both the methods are working for me.
I just wanted to know which method is more efficient and why?
Generally speaking with modern CPU (having caches). Reading and array backward is usually a very bad idea as it generates a lot of cache misses. Unless (of course) the array was already in cache.
So first approach seems to be better from that point of view.

Deciding the base condition in backtracking recursive algorithm

I was solving the N Queen problem where we need to place 4 queens on a 4 X 4 chess board such that no two queens can attack each other. I tried this earlier but my approach did not involve backtracking, so I was trying again. The code snippets are
int size=4,i,j;
int arr[4][4];
int lastjindex[4]; // to store the last location which we may need to backtrack
void placeQueen(int i,int j)
{
int availableornot=0;
for(j=0;j<size;j++)
{
if(isAvailable(i,j)==1)
{
availableornot=1;
break;
}
}
if(availableornot==1)
{
arr[i][j]=1;
lastjindex[i]=j;
if((i+1)!=size)
{
placeQueen(i+1,0);
}
}
else
{
// no column was availabe so we backtrack
arr[i-1][lastjindex[i-1]]=0;
placeQueen(i-1,lastjindex[i-1]+1);
}
}
The isAvailable() method returns 1 if arr[i][j] is not under attack, else it returns 0.
int isAvailable(int i,int j)
{
int m,n,flag=0;
for(m=0;m<i;m++)
{
for(n=0;n<size;n++)
{
int k=abs(i-m);
int l=abs(j-n);
if(arr[m][j]==0 || arr[k][l]==0)
{
flag=1;
break;
// means that spot is available
}
}
}
return flag;
}
I call the above method from main as
placeQueen(0,0);
My program compiles successfully but it prints all zeroes.
Is there any problem with my recursion? Please help me correct my code as I am trying to learn how to implement backtracking algorithms!
Also I am not able to decide the base condition to end recursion. How do I choose it here?
There's no printing in the code you posted. If you print after you have backtracked, you will be back to the initial condition of no queens on the board. Print after you have placed N queens, which is also the end condition for recursion. If you only want to print one solution, exit after printing, or set a flag that tells the caller that you're done so you pop all the way out. If you print all solutions, that will include reflections and rotations. You can eliminate one axis of reflection by only placing queens within size/2 in the first level.
Also, there are some clear logic errors in you code, such as
arr[m][j]==0 || arr[k][l]==0
A queen can only be placed if it isn't attacked on the file and it isn't attacked along a diagonal. Use a debugger or add printfs to your code to trace where it is trying to place queens -- that will help you figure out what it is doing wrong.
And aside from being wrong, your isAvailable is very inefficient. You want to know if the [i,j] square is attacked along the file or a diagonal. For that you should have a single loop over the rows of the previous queens for (m = 0; m < i; m++), but you only need three tests, not a loop, to check the file and the diagonals. As soon as you find any previous queen on a file or diagonal, you're done, and the square isn't available -- return false. (And ignore people who tell you that a function should only have one return -- they are wrong, and there are lengthly discussions here at SO and even scientific studies of error rates in code that bear this out.) Only if no previous queen is found is the square available.
Your placeQueen is also wrong. For each available square on a row, you need to place a queen and then recurse, but you're just finding the first available square. And backtracking is achieved simply by removing the queen you placed and then returning ... the previous level of placeQueen will try the next available spot.
Again, trace the code to see what it's doing. And, even more importantly, think through the logic of what is needed. Write your algorithm in words, convince yourself that it will solve the problem, then write the code to carry out the algorithm.
#include <stdio.h>
#define SIZE 4
int size=SIZE;
int arr[SIZE][SIZE] = { 0 };
void placeQueen(int col){
int r,c;
if(col == size){//all queen put!
//print out
for(r = 0;r<size;++r){
for(c = 0;c<size;++c)
printf("%d", arr[c][r]);
printf("\n");
}
printf("\n");
return ;
}
for(r=0;r<size;++r){
if(isAvailable(col, r)==1){
arr[col][r]=1;
placeQueen(col+1);
arr[col][r]=0;//reset
}
}
}
int isAvailable(int col,int row){
int c;
for(c=0;c<col;++c){
int d = col - c;
if(arr[c][row]==1)
return 0;//queen already same row
if(row+d < size && arr[c][row+d]==1 || row-d >= 0 && arr[c][row-d]==1)
return 0;//queen already same slanting position
}
return 1;
}
int main(){
placeQueen(0);
return 0;
}

Resources