1

Here is my program it is compiling and running without syntax errors.How ever it does not sort the array.The problem lies in where I am passing the array in function

#include<stdio.h>
#include<string.h>
int partition (int *,int,int);
void quicksort (int *,int,int);
static int call=0;
int main()
{
int i,j,choice;
int length;
int a[]={81, 12, 90, 3, 49, 108, 47};
i=0;

length=sizeof(a)/sizeof(a[0]);
quicksort(a,0,length-1);
printf("the sorted array is\n");
for(i=0;i<length;i++)
 printf (" %d ",a[i]);
}
int partition(int *num,int p,int r)
{
 int x,j,i,temp,bak;
  x=num[r];
  i=p-1;
       for(j=0;j<=r-1;j++)
  { 
         if(num[j]<=x)
     {
      i=i+1;
       temp=num[i];
       num[i]=num[j];
       num[j]=temp;


      {
       printf(" %d",num[bak]);
        }

     }  
  }
  num[i+1]=num[r];

 return i+1;
}

void quicksort (int *num,int p,int r)
{ 
 int q;
 if (p<r)
  {
    call++;

    q=partition(num,p,r);
        quicksort(num,p,q-1);
        quicksort(num,q+1,r);
  }
}    

The above way of passing array in functions is that right that is what I want to know because that is giving problem in function partition.

Inside the function partition when swapping happens then I tried printing the array there itself (it is not sorted array but just to see upto what point things reached) then I saw that only 2 or 3 elements of array which I had passed are being printed and rest of the array is lost some where.So my doubt is array is not being passed properly.

To be able to see as what is the problem with array passing in a function I wrote a smaller program ka1.c

#include<stdio.h>
void pass(int *);
int main ()
{
int a[]={3,5,61,32,12};
pass(a);
}
void pass (int *num)
{
int i,j;
 j=sizeof(num)/sizeof(num[0]);
 for (i=0;i<j;i++)
 printf(" %d",num[i]);
}

Now when I run the above code I get output just

 3 5

I was expecting the complete array to be printed in output of ka1.c. Where as if you notice rest of the array is not getting printed.Where did that go? I have used the same logic in quicksort also hence I feel the error is same in both cases.

UPDATE1
After the comment below I checked the length of array recieved in quicsort.c paritition function via

sizeof(num)/sizeof(num[0]);

and found of original array

int a[]={81, 12, 90, 3, 49, 108, 47};

which is having length 7 here when I passed it in the function partition the length is only 2. The same is case with program ka1.c So why only length is 2 in both cases?

UPDATE2
As the suggestions given below now I have passed on the length also

#include<stdio.h>
#include<string.h>
int partition (int *,int,int,int);
void quicksort (int *,int,int,int);
static int call=0;
int main()
{
int i,j,choice;
int length;
int a[]={81, 12, 90, 3, 49, 108, 47};
i=0;
printf("the sorted array is\n");
length=sizeof(a)/sizeof(a[0]);
printf("length of array %d\n",length);
printf("quick sort called in main\n");
quicksort(a,0,length-1,length);
for(i=0;i<length;i++)
 printf (" %d ",a[i]);
}
int partition(int *num,int p,int r,int june)
{
 int x,j,i,temp,bak,length;
  x=num[r];
  i=p-1;
  bak=0;
  printf("inside the partition\n");
 printf("length of june recieved =%d \n",june);
  for(j=0;j<=r-1;j++)
  { 
    if(num[j]<=x)
     {
      i=i+1;
       temp=num[i];
       num[i]=num[j];
       num[j]=temp;
    printf("printing array after swap\n");
      for(;bak<7;bak++)
      {
           printf(" %d ",num[bak]);
          }
     }  
  }
  num[i+1]=num[r];

 return i+1;
}

void quicksort (int *num,int p,int r,int june)
{ 
 int q,bbc,ccd;
 if (p<r)
  {
    call++;
         printf("partition called  %d times p=%d r=%d\n",call,p,r);
    printf("before sending to function length of june=%d \n",june);
    q=partition(num,p,r,june);
    bbc=q-1-p+1;
        quicksort(num,p,q-1,bbc);
        ccd=r-q-1+1;
        quicksort(num,q+1,r,ccd);
  }
}

But the program is still failing to print the sorted array. You can compile and run the above code.

SOLVED
Finally with help of replies below I have been able to solve the above problem. The mistake lied in function partition in statement

  for (j = 0; j <= r - 1; j++)

instead it should have been

  for (j = p; j <= r - 1; j++)

note j=p and j=0 here

j=0

is wrong since when recursively second partition is tried to be sorted it started disturbing the first partition and hence the result was also wrong.

In this program I faced a problem in using gdb to debug a recursive function. Please check this thread also Debugging recurssion was quite tricky.

SO the correct code is

#include<stdio.h>
#include<string.h>
int partition (int *, int, int, int);
void quicksort (int *, int, int, int);
static int call = 0;
int
main ()
{
  int i, j, choice;
  int length;
  int a[] = { 81, 12, 90, 3, 49, 108, 47 };
  i = 0;
  printf ("the sorted array is\n");
  length = sizeof (a) / sizeof (a[0]);
  printf ("length of array %d\n", length);
  printf ("quick sort called in main\n");
  quicksort (a, 0, length - 1, length);
  for (i = 0; i < length; i++)
    printf (" %d ", a[i]);
}

int
partition (int *num, int p, int r, int june)
{
  int x, j, i, temp, bak, length;
  x = num[r];
  i = p - 1;
  bak = 0;
  for (j = p; j <= r - 1; j++)
    {
      if (num[j] <= x)
    {
      i = i + 1;
      temp = num[i];
      num[i] = num[j];
      num[j] = temp;
    }
    }
  temp=num[i+1];
  num[i + 1] = num[r];
  num[r]=temp;
  return i + 1;
}

void
quicksort (int *num, int p, int r, int june)
{
  int q, bbc, ccd;
  if (p < r)
    {
      call++;
      q = partition (num, p, r, june);
      bbc = q - 1 - p + 1;
      quicksort (num, p, q - 1, bbc);
     ccd=r-q+1;
      quicksort (num, q + 1, r, ccd);
    }
}
Community
  • 1
  • 1
Registered User
  • 5,173
  • 16
  • 47
  • 73

3 Answers3

2

The problem is in the way you are calculating the length of teh array.......try simply giving the number of elements in the array as the parameter for the quicksort method....i guess u will have the right answer... and also i agree to the point made....try and passing the length of the array with the array.....try both and tell me which works...:) NEW CODE:

#include<stdio.h>
#include<string.h>
//int partition (int *,int,int);
void q_sort(int*,int,int);
void quicksort (int *,int);
static int call=0;
int main()
{
int i,j,choice;
int length;
int a[]={81, 12, 90, 3, 49, 108, 47};
i=0;
printf("the sorted array is\n");
length=sizeof(a)/sizeof(a[0]);
printf("length of array %d\n",length);
printf("quick sort called in main\n");
quicksort(a,length);
for(i=0;i<length;i++)
 printf (" %d ",a[i]);
}
/*int partition(int *num,int p,int r)
{
 int x,j,i,temp,bak,length;
  x=num[r];
  i=-1;
  bak=0;
  printf("inside the partition\n");
  for(j=0;j<=r-1;j++)
  {
    if(num[j]<=x)
     {
      i=i+1;
       temp=num[i];
       num[i]=num[j];
       num[j]=temp;
    printf("printing array after swap\n");
      for(;bak<7;bak++)
      {
           printf(" %d ",num[bak]);
          }
     }
  }
  num[i+1]=num[r];

 return i+1;
}
*/
/*void quicksort (int *num,int p,int r)
{
 int q,bbc,ccd;
 if (p<r)
  {
    call++;
         printf("partition called  %d times p=%d r=%d\n",call,p,r);
    q=partition(num,p,r);
    bbc=q-1-p+1;
        quicksort(num,p,q-1);
        ccd=r-q-1+1;
        quicksort(num,q+1,r);
  }
}*/
void quicksort(int numbers[], int array_size)
{
  q_sort(numbers, 0, array_size - 1);
}


void q_sort(int numbers[], int left, int right)
{
  int pivot, l_hold, r_hold;

  l_hold = left;
  r_hold = right;
  pivot = numbers[left];
  while (left < right)
  {
    while ((numbers[right] >= pivot) && (left < right))
      right--;
    if (left != right)
    {
      numbers[left] = numbers[right];
      left++;
    }
    while ((numbers[left] <= pivot) && (left < right))
      left++;
    if (left != right)
    {
      numbers[right] = numbers[left];
      right--;
    }
  }
  numbers[left] = pivot;
  pivot = left;
  left = l_hold;
  right = r_hold;
  if (left < pivot)
    q_sort(numbers, left, pivot-1);
  if (right > pivot)
    q_sort(numbers, pivot+1, right);
}
  • @Abhimanyu Srivastava I have now given the array length as parameter as per your suggestion.But it is not giving a sorted output. – Registered User Jun 21 '11 at 11:40
  • @Abhimanyu Srivastava while debugging one important mistake I caught is in fucntion partition `i=-1`;I had given where as in Coreman it is given as `i=p-1;` – Registered User Jun 21 '11 at 11:50
  • @Abhimanyu Srivasta I have updated the code in case you want to copy use the new one – Registered User Jun 21 '11 at 11:55
  • actually there is some error in your algorithm....u just passed the length two times in quick sort.....go through the algorithm again and implement it seeing where the length of the array is required in the parameter there u pass the length.. – Abhimanyu Srivastava Jun 21 '11 at 11:56
  • @Abhimanyu Srivastava you mean to say `void quicksort (int *num,int p,int r,int june) { int q,bbc,ccd; if (p – Registered User Jun 21 '11 at 11:58
  • yup....u just have to have 3 parameters......one for the array...the other two for the starting and endpoint..... – Abhimanyu Srivastava Jun 21 '11 at 11:59
  • and u have taken -1 there......obviously that is why it is giving garbage values........ – Abhimanyu Srivastava Jun 21 '11 at 12:01
  • @Abhimanyu Srivastava the fourth parameter is the length of array is that not correct? – Registered User Jun 21 '11 at 12:09
  • @registered...i have entered the corrected code....check it out....ask if any doubts.... – Abhimanyu Srivastava Jun 21 '11 at 12:14
  • @Abhimanyu Srivastava I got the correct sorting sequence from your code.But I am trying to debug my code. gdb is recursively going here and there so it is a bit difficult for me to catch it.There was one more error in my code in function partition before statement `return i+1; ` the `a[i+1]` should be swapped with `a[r]`.So I have caught till here in my code. The break points in gdb are line no 17,59,60,26,62,64 but at line 63 ,the call to line 53 is again made and then my break points here do not work i.e. what happens is the code does get evaluates in partition function but gdb doesn'tshow – Registered User Jun 21 '11 at 13:47
  • @Abhimanyu Srivastava I think I catched the error the function quicksort in my program partitions the array and keeps doing recursively.There is no recursive condition which is being checked, `void quicksort (int *num, int p, int r, int june) { int q, bbc, ccd; if (p < r) { call++; q = partition (num, p, r, june); bbc = q - 1 - p + 1; quicksort (num, p, q - 1, bbc); ccd = r - q - 1 + 1; quicksort (num, q + 1, r, ccd); } }` – Registered User Jun 21 '11 at 15:41
  • @registered.see what you are doing wrong is that u r not taking into consideration what the algorithm is doing....u r simply going with the texted algorithm.....i suggest u one thing.....go through my code thoroughly...debug it.....check what steps it follows for the array u took....u will find the actual mechnasim..then u code urself... – Abhimanyu Srivastava Jun 21 '11 at 17:03
  • @Abhimanyu Srivastav hey man thanks for your efforts I have been able to finally debug my problem and my code also is working correctly.The error like in function partition I was doing `for (j = 0; j <= r - 1; j++)` where as what is needed is `for (j = p; j <= r - 1; j++)` note `j=p` because of which when second recursive call to quicksort from within quicksort was made then it started disturbing the original partition.I am posting the correct code also. – Registered User Jun 21 '11 at 17:34
  • @registered....great work...tell me ur name...i m tired of writing registered here again and again..:D...and glad i could help......:)...and please be kind enough to vote and accept the answer...:P – Abhimanyu Srivastava Jun 21 '11 at 17:40
1

You need to put a ; at the end of the function declaration before main:

void pass(int *) ;
                 ^
codaddict
  • 445,704
  • 82
  • 492
  • 529
1

You have to pass the size of the array along with the array itself. The function receiving the array cannot determine its size. The receiving function only sees num as a pointer, so when you use sizeof(num) it returns the size of the pointer num, not the size of the memory allocated for the array in the main function. So, you have to do something like this:

#include<stdio.h>

void pass(int *, int);
int main ()
{
    int a[]={3,5,61,32,12};
    int length;
    length = sizeof(a)/sizeof(a[0]);
    pass(a, length);
}
void pass (int *num, int size)
{
    int i;  
    for (i=0;i<size;i++)
        printf(" %d",num[i]);
}

This post explains a similar issue in more detail: Passing an array as an argument in C++

Community
  • 1
  • 1
iceaway
  • 1,204
  • 1
  • 8
  • 12