【问题标题】:unable to pass array properly in quicksort无法在快速排序中正确传递数组
【发布时间】:2011-09-19 09:27:57
【问题描述】:

这是我的程序,它正在编译和运行,没有语法错误。它没有对数组进行排序。问题在于我在函数中传递数组的位置

#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);
  }
}    

上述在函数中传递数组的方法是我想知道的正确方法,因为这会给函数分区带来问题。

在发生交换时在函数分区内部然后我尝试在那里打印数组本身(它不是排序数组,只是为了看看事情达到了什么点)然后我看到我传递的数组中只有 2 或 3 个元素是正在打印并且数组的其余部分丢失了一些地方。所以我怀疑数组没有被正确传递。

为了能够查看数组传入函数的问题是什么,我编写了一个较小的程序 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]);
}

现在当我运行上面的代码时,我得到的只是输出

 3 5

我期待 在 ka1.c 的输出中打印完整的数组。 好像你注意到数组的其余部分没有被打印出来。那去哪儿了? 我在快速排序中也使用了相同的逻辑,因此我觉得两种情况下的错误都是一样的。

更新1
在下面的评论之后,我通过

检查了 quicsort.c 分区函数中收到的数组的长度
sizeof(num)/sizeof(num[0]);

找到原始数组

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

当我在函数分区中传递它时,它的长度为 7 长度只有2。 程序 ka1.c 也是如此,那么为什么在这两种情况下,长度都只有 2?

更新2
正如下面给出的建议一样,我也传递了长度

#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);
  }
}

但程序仍然无法打印已排序的数组。 可以编译运行上面的代码。

已解决
最后在下面的回复的帮助下,我已经能够解决上述问题。 错误在于语句中的函数划分

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

应该是这样的

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

注意 j=pj=0 这里

j=0

是错误的,因为当尝试对第二个分区进行递归排序时,它开始干扰第一个分区,因此结果也是错误的。

在这个程序中,我在使用 gdb 调试递归函数时遇到了问题。 也请查看this thread 调试递归非常棘手。

所以正确的代码是

#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);
    }
}

【问题讨论】:

  • -1:您是否尝试过在小型数据集的调试器中单步执行您的代码?你发现了什么?
  • 到底是什么问题?什么不工作?
  • @iceway 在发生交换时在函数分区内然后我尝试在那里打印数组本身(它不是排序数组,但只是为了看看事情达到了什么点)然后我看到只有 2 或 3 个元素数组的一部分正在打印,而数组的其余部分在某些地方丢失了。
  • 你有没有试过输出长度的值???如果是,它是什么来的?
  • @Abhimanyu Srivastava 好点,收到的数组长度只是我给出的完整输入的两个数字。

标签: c arrays function sorting quicksort


【解决方案1】:

问题在于您计算数组长度的方式......尝试简单地将数组中的元素数作为快速排序方法的参数......我猜你会有正确答案... 而且我同意所提出的观点....尝试将数组的长度与数组一起传递......尝试两者并告诉我哪个有效......:) 新代码:

#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 我现在已根据您的建议将数组长度作为参数提供。但它没有给出排序输出。
  • @Abhimanyu Srivastava 在调试时发现的一个重要错误是在功能分区i=-1;我已经给出了在Coreman 中给出的位置i=p-1;
  • @Abhimanyu Srivasta 我已经更新了代码,以防你想复制使用新代码
  • 实际上你的算法有一些错误......你只是在快速排序中传递了两次长度......再次通过算法并实现它,看看数组的长度在哪里参数中需要你传递长度..
  • @Abhimanyu Srivastava 你的意思是说void quicksort (int *num,int p,int r,int june) { int q,bbc,ccd; if (p&lt;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); } } 这部分有问题。
【解决方案2】:

您必须将数组的大小与数组本身一起传递。接收数组的函数无法确定其大小。接收函数仅将 num 视为指针,因此当您使用 sizeof(num) 时,它返回指针 num 的大小,而不是 main 函数中为数组分配的内存大小。所以,你必须这样做:

#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]);
}

这篇文章更详细地解释了一个类似的问题: Passing an array as an argument in C++

【讨论】:

  • 也感谢您的指点,因为我终于能够解决它+1:D
【解决方案3】:

你需要在函数声明的末尾加上;main

void pass(int *) ;
                 ^

【讨论】:

  • 非常适合指出这个错误我正在更新我的问题,请检查我要发布的输出。
  • 现在检查我已经更新了在 quicksort.c 和 ka1.c 两个程序中接收到的数组长度只是整个输入的 2 个数字。
  • 感谢您帮助解决此错误。终于解决了。为您的消息 +1。
猜你喜欢
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 2020-08-14
相关资源
最近更新 更多