我目前正在尝试用C编写一个简单的Quicksort代码,但我似乎无法理解C语法和指针。我习惯用Java编码,所以我对如何返回int数组感到困惑,以及我做错了什么。
这是我现在的代码,非常感谢任何帮助。
#include <stdio.h>
#define MAX 100
int input[MAX];
int* QuickSort(int A[], int n);
int* combine (int first[], int pivot, int last[]);
//main method to run program
int main()
{
int i, n;
//read in input and store values in array named input
printf ("Enter several numbers separated by spaces or returnsand ended by Ctrl-D:\n");
for (n = 0; n < MAX && scanf("%d", &input[n]) != EOF; n++);
//runs QuickSort on the array
int new[n] = QuickSort(input, n);
printf("Here is your sorted array:\n");
//goes through sorted array to print values
for (i = 0; i < n; i++)
printf("%d\n", new[i]);
}
int* QuickSort(int A[], int n)
{
//if array has 1 value or is empty, automatically return
if (n <= 1)
return A;
int pivot = A[0];
int less[n/2];
int more[n/2];
int lesscount = 0;
int morecount = 0;
int i;
for (i = 1; i<n; i++)
{
if (A[i] <= pivot)
{
less[lesscount] = A[i];
lesscount++;
}
else if (A[i] > pivot)
{
more[morecount] = A[i];
morecount++;
}
}
int size = n/2;
return combine(QuickSort(less, size), pivot, QuickSort(more, size));
}
int* combine (int first[], int pivot, int last[])
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
int n;
for (n =0; n<firstsize; n++)
{
combined[n]= first[n];
}
combined[n]=pivot;
n++;
int m;
for (m =0; m<totalsize; m++)
{
combined[n] = last[m];
n++;
}
return combined;
}
答案 0 :(得分:1)
指针是一个可以取消引用和访问的内存地址。它与一个对象非常不同,并且(很可能)只是一个8字节的值。而在Java中你可能能够传递对象(它确实指向一些内存),在C中你必须更加小心你所指向的记忆。
特别是stack
和heap
之间存在差异。 stack
是您的程序用于跟踪局部变量并将自动分配空间的内容。另一方面,heap
通常是您需要自己管理的东西。特别是,除非您明确分配堆地址,否则您将无法获得堆地址(即使用malloc
)。为什么区别?因为堆栈会自动分配空间,但也会在函数返回时自动释放空间。
为什么这适用于你?
让我们来看看你的一些功能:
int* combine (int first[], int pivot, int last[])
/* i.e., int* combine (int *first, int pivot, int *last) */
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
/* The rest of the code */
return combined;
}
你正在向任何正在调用你的函数的人返回combined
,一个堆栈分配的变量。这样做是合法的&#34;从严格意义上说,它是不正确的,因为一旦你从函数返回,程序将自动释放内存。这意味着你可能会得到一些非常令人困惑的结果和/或错误。
在你的情况下,quicksort不需要更多的空间,只需要对变量进行一些巧妙的操作。因此,您实际上甚至不需要使用任何子数组,也不需要返回任何数组。关于指针的巧妙之处在于你获得了一个内存地址。因此,如果您更改了指向的内容(即A[0] = x
),那么任何其他也知道A
的函数都会看到该更新。
您的初始实施也不完全正确。 Quicksort可以大致分为两个步骤:分区和组合。分区时,您希望将所有小于枢轴值的值与大于枢轴值的所有值分开。但是,因为您还不知道有多少,假设您在每个分区中都有size/2
会给您带来麻烦。
对于分区,您可以使用就地迭代方法。像这样:
while index < end:
if A[index] < pivot:
index ++
else if A[index] > pivot:
swap(A[index], A[end])
end --
swap(pivot, A[index])
(上面可能有一些错误。)基本的想法是,通过用两个索引跟踪下部和上部,你可以添加&#34;您正在与正确的一方进行比较的当前值(通过移动到下一个索引,或者交换和减少结束)。通过这样做,您不需要处理内存分配。
然后,递归步骤将知道您的子片段在哪里,并递归地调用每个子片段。