qsort一个类对象列表

时间:2017-08-03 18:32:12

标签: c++ list class qsort

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

 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')

3 个答案:

答案 0 :(得分:2)

你可以使用std :: sort和lambda expresion,这是一个例子:

#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";

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

答案 1 :(得分:0)

Stl list有自己的sort函数,可以接受compare函数。您可以编写一个比较函数,它接受两个参考 Point 对象并将其传递给 myPoints.sort(..)

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

答案 2 :(得分:0)

qsort是旧学校C.它需要4个参数:

  

ptr - 指向要排序的数组的指针

     

count - 数组中元素的数量

     

size - 数组中每个元素的大小(以字节为单位)

     

comp - 比较函数,如果第一个参数小于第二个参数,则返回负整数值,   如果第一个参数大于第二个参数,则为正整数值;如果参数相等,则为零。

from std::qsort

它给出的是

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

指向list的指针会杀死你。我怀疑这是std::list,但不能证明这一点。无论它是什么,它都是一个模板化的数据结构,这使事情变得多毛。它不是数组,不应该用作数组。

qsort试图将它用作数组,并引用Dune:

  

他们尝试过但失败了?

     

他们试过并死了。

现在我们知道,list可能是一个非常simple structure,其中包含一个Point数组,该数组完全可以与实例的开头对齐 - 地址包含的数组的内容与实例化list的地址相同 - 但崩溃表明不然。

如果list是动态数组(由其用法建议)或链表(由名称和用法建议),那么list实例甚至不包含其数据。它包含指向数据的指针。 qsort没有可以使用的数组,它会快速浏览list中存储的少量数据,从另一方面进入Undefined Behaviour这个狂野而古怪的世界。也就是说,您将非数组传递给qsort的实例已经达到了未定义的行为。

如果list具有迭代器接口,解决方案是使用C ++的built in std::sort。如果list确实是std::list,则可能会有性能优势in using std::list::sort。如果两者都不是真的并且list是一个不幸的命名自定义类,那么你必须编写自己的排序例程(或者做一些聪明的事情,然后查看自定义类以支持库容器)。