2

这是我的问题:我有一个结构:

struct point
{
    int x;
    int y;
};

然后我有一个数组:

for (int i = 0;i < n;i++)
{
    arr[i].x=rand() % n + 1;
}

我将quicksort函数定义如下:

 void quicksort(int *a, int left, int right);

我想按X坐标对点进行排序,所以我调用quicksort

quicksort(arr.x, 0, n-1);

这是错误消息:

错误:在'arr'中请求成员'x',它是非类类型'point [(((unsigned int)(((int)n) + -0x000000001)) + 1)]'

抱歉,如果问题太愚蠢或表述不当,事实是我是新手,我真的很愿意尽可能多地学习,非常感谢您的帮助!

4

7 回答 7

3

如果你总是想按 排序x,那么你可以将它硬编码到排序函数中,然后将一个指针传递给数组进行排序:

void quicksort(point * arr, int left, int right) {
    // test points with 
    // if (arr[i].x < arr[j].x) {/* i sorts before j */}
}

quicksort(arr, 0, n-1);

要指定要排序的类成员,您需要一个指向成员的指针,而不是指针;就像是:

void quicksort(point * arr, int point::*member, int left, int right){
    // test points with 
    // if (arr[i].*member < arr[j].*member) {/* i sorts before j */}
}

quicksort(arr, &point::x, 0, n-1);

更一般地,您可以遵循std::sort并接受任何比较函子的示例:

template <typename RandIter, typename Compare>
void quicksort(RandIter begin, RandIter end, Compare compare) {
    // test points with 
    // if (compare(*it1, *it2)) {/* *it1 sorts before *it2 */}
}

quicksort(arr, arr+n, 
    [](point const &lhs, point const &rhs) {return lhs.x < rhs.x;});

当然,除非您正在学习如何实现排序算法,否则只需使用std::sort.

于 2013-09-23T15:42:34.233 回答
0

假设这是出于学术目的(为什么要声明自己的排序算法而不是使用已经使用自定义比较器实现的排序算法之一?),您可以通过以下几种方式执行此操作:

大批

std::array<point, 10> myArray; // declares an array of size 10 for points
template<size_t N>
void quicksort(std::array<point, N>& arr, ...)
{
    // implement sort operating on arr
}

向量

std::vector<point> myVector; // declares a dynamic array/vector of points
void quicksort(std::vector<point>& arr, ...)
{
    // implement sort operating on arr
}

如果出于某种可怕的原因,您想将其保留在 C 中:

遗产

const size_t SIZE = 10;
point arr[SIZE]; // declare an array of 10 points
void quicksort(point* p, const size_t n, ...)
{
    // implement sort operating on elements in p passing in SIZE for n
}
于 2013-09-23T15:44:02.317 回答
0

我宁愿将函数定义为:

 void quicksort(void *a,int left,int right, size_t size, int (*fp)(void*,void*));

size是数组的一个元素的大小,fp是一个比较函数,如果两个参数相等,则返回 true。现在您可以将调用传递为:

quicksort(arr,0,n-1,sizeof(arr)/sizeof(arr[0]), compare);

其中函数比较类似于:

int compare(void* a, void* b) { return *((int*)a) >= *((int*)b); }  

我认为其余的功能实现是微不足道的。

于 2013-09-23T15:46:27.707 回答
0
quicksort(arr,0,n-1);

然后在内部quicksort,尝试比较arr[i].x

于 2013-09-23T15:40:18.357 回答
0

您的代码存在一些问题。
1. quicksort 接受 int* 但你试图传递 int 值 x
2. 你试图传递 int 但你实际上调用了一个未定义的变量 arr.x

您需要做的是以 &arr[i].x 的形式调用,但要完成您想要的,您可能希望将整个结构作为指针传递。

于 2013-09-23T15:40:44.970 回答
0

您需要arr作为参数传递,因为这是要排序的数组。arr.x是没有意义的。您没有将字符串"arr.x"作为参数传递,该参数可以以某种方式解释为 x 字段上的排序 - 当编译器看到这一点时,它正在寻找一个不存在的x元素,如错误消息所示 - 只有(eg ) 的元素具有arr元素(作为 访问)。arrarr[0]xarr[0].x

于 2013-09-23T15:41:16.787 回答
0

(几乎)当你真的想传递一个指向对象的指针时,永远不要试图通过传递一个指向成员的指针来欺骗系统。按照格里杰什的建议去做。传递成员可能会导致可怕的副作用。例如,快速排序会将所有整数排序在一起,而不管其中哪些是 X,哪些是 Y。在较温和的情况下,您可能会得到错误的比较标准,并且通常难以调试效果,例如不正确的指针优化。如果您需要传递对象指针,请对编译器诚实并传递对象指针。很少有例外,主要与低级系统编程有关,其中函数调用的“另一端”将无法处理对象。

于 2013-09-23T15:48:19.130 回答