对 class 个对象的列表进行排序

qsort a list of class objects

我正在为现有库编写排序代码,因此无法更改数据模型 我有以下

 class Point
 {

   //Some functions 
   public:
       float x, y, z;

  };

int less_than_key (const void *arg1, const void *arg2)
 {

      Point *r1 = (Point*) arg1;
      Point *r2 = (Point*) arg2;

      if(r1->z < r2->z )
        return -1;

     else if(r1->z > r2->z )
       return 1;
    else
       return 0;
}

int main()
{
   list<Point> myPoints; 

    Point p;
    p.x = 0;
    p.y = 0;
    p.z = 0;
    myPoints.push_back(p);

    p.x = 0;
    p.y = 0;
    p.z = 6;
    myPoints.push_back(p);

    p.x = 0;
    p.y = 0;
    p.z = 2;
    myPoints.push_back(p);

    for(int i=0; i<myPoints.size(); i++)
      cout<<" Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";

    qsort(&myPoints, myPoints.size(), sizeof(Point), less_than_key);

    for(int i=0; i<myPoints.size(); i++)
      cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
 }

我想根据 z 值对对象进行排序。 我期望的输出如下

 Before sorting 
 Point 0, 0, 0
 Point 0, 0, 6
 Point 0, 0, 2

 After sorting 
 Point 0, 0, 0
 Point 0, 0, 2
 Point 0, 0, 6

当我 运行 以下代码时,它在排序调用期间崩溃,我得到以下错误

  terminated with signal 11

我在其他解决方案中读到我应该通过以下列表

   qsort(&myPoints[0], myPoints.size(), sizeof(Point), less_than_key);

但是当我尝试编译它时,我得到以下结果

  no match for 'operator[]' (operand types are 'std::list<Point>' and 'int')

Stl 列表有它自己的接受比较函数的排序函数。您可以编写一个比较函数,该函数采用两个引用 Point 对象并将其传递给 myPoints.sort(..)

见[1]http://www.cplusplus.com/reference/list/list/sort/

您可以将 std::sort 与 lambda 表达式一起使用,这是一个示例:

#include <algorithm>

std::list<Point> myPoints;

//adding points to list...

std::sort(myPoints.begin(), myPoints.end(), [](const Point& lhs, const Point& rhs)
{
   return lhs.z < rhs.z;
});

for(int i=0; i<myPoints.size(); i++)
  cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";

上面的代码将排序,然后打印排序后的点列表

qsort 是老派的 C。它需要 4 个参数:

ptr - pointer to the array to sort

count - number of elements in the array

size - size of each element in the array in bytes

comp - comparison function which returns ​a negative integer value if the first argument is less than the second, a positive integer value if the first argument is greater than the second and zero if the arguments are equal.

from std::qsort

给出的是

  • 指向 list
  • 的指针
  • 数组中的元素数
  • 数组中每个元素的大小(以字节为单位)
  • 比较函数

是指向 list 的指针要了你的命。我怀疑这是 std::list,但无法证明这一点。不管它是什么,它都是一个模板化的数据结构,这让事情变得毛茸茸。它不是数组,不应用作数组。

qsort 尝试将其用作数组,并引用沙丘:

They tried and failed?

They tried and died.

现在,据我们所知,list 可能是一个非常 simple structure,其中包含一个 Point 的数组,其位置完美地与实例的开头对齐--包含数组的地址与实例化 list 的地址相同——但崩溃表明并非如此。

并且如果 list 是动态数组(根据其用法建议)或链表(根据名称和用法建议),则 list 实例甚至不包含其数据.它包含指向数据的指针。 qsort 没有数组可供使用,它会快速 运行 通过存储在 list 中的少量数据,从另一边进入狂野古怪的 [=34= 世界].也就是说,如果您将非数组传递给 qsort 实例,您已经遇到未定义行为。

解决方案是使用 C++ 的 built in std::sort if list has an iterator interface. if list is really std::list there may be performance advantages in using std::list::sort。如果两者都不是真的,并且 list 是一个不幸命名的自定义 class,您将不得不编写自己的排序例程(或者做一些聪明的事情并放弃自定义 class 以支持库容器)。