Usage and understanding of c + + sorting related parameter "cmp"

(most of the articles are reproduced in: https://www.jianshu.com/p/223d4d52ece0 )
For the sort function (the algorithm header file is required), its cmp can be "function" or "object"

bool myfunction (int i,int j) { return (i<j); }

struct myclass 
{
  bool operator() (int i,int j) { return (i<j);} 
} myobject;
int main () 
{
  int myints[] = {32,71,12,45,26,80,53,33};
  vector<int> myvector (myints, myints+8);//Put into container vector
  sort(myfunction); //The argument cmp is a function
  sort(myobject);//The parameter cmp is a structure object
  return 0;
}

▲ note: the return type of the function myfunction here is bool. When it returns true, it is considered as I < J, and when it returns false, it is considered as I > = J. by default, the sorting is from small to large. Therefore, for reverse sorting, you only need to change return (I < J) to return (I > J).
In addition, it is worth mentioning that the bool operator() (int i,int j) function of the structure is actually an overloaded function of the operator. The brackets are overloaded, which is equivalent to the usual operator + (...). Therefore, for the structure object myobject, you can operate bool re = myobject(1,2);, The result will return false, and the written form is the same as that of the function (it is convenient to understand and remember. In fact, the parameters cannot be converted from "function" type to "object" type, but are overloaded)

-------------------------(split)----------------------------------------

For qsort function, cmp is the function name

int values[] = { 40, 10, 100, 90, 20, 25 };
int cmp(const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}
int main ()
{
  int n;
  qsort (values, 6, sizeof(int), cmp);
  return 0;
}

▲ note: the function cmp here must match the prototype int (_cdecl * _ptfunccompare) (void const, void const). To put it bluntly, the return value is int, the function name is optional, and the function parameter type should be void const * (the const order is adjustable). Inside (int)a is actually: first forcibly convert the void * pointer a into an int * pointer, and then compare the pointing object in * ((int *) A. if it is other float/double, needless to say, change it to (double) and so on.
Incidentally, if the return value is less than 0 (generally written as return - 1), it is considered that a is smaller than b, if it is equal to 0, it is considered equal, and if it is greater than 0 (generally written as return 1), it is considered that a is larger than b. If you want to sort from large to small, you can change it.

qsort( (void *) & elem1, (void *) & elem2 );
Return value of the Compare functiondescribe
<0elem1 will be ranked ahead of elem2
>0elem1 will be ranked behind elem2
=0elem1 equals elem2

For STL containers, such as priority queue (max / min heap, the default is Max heap)_ For the queue class, its template parameters can only be the class / structure name, so its "cmp" should be the structure name (note that it is not the myobject mentioned above, but the structure name), and there should be an operator () overloaded function inside.

struct cmp  //Custom name
{
    bool operator ()(int a, int b)
    {
        return a.val < b.val;
    }
}
int main()
{
    /*Header file queue is required. The first template parameter is data type, the second is container type, and the third is structure*/
    priority_queue<int, vector<int>, cmp> t;  
    return 0;
} 

▲ note: the cmp return value here is bool type, and the function is an overloaded function with brackets.
It is worth mentioning that there are many patterns:

class A
{
  int val;
  bool operator <(int a, int b) const {return a<b;}  //Const cannot be omitted here. You can write const int &a and other parameters
//Friend bool operator < (const int & A, const int & B) / / friend functions can also be used
}
int main()
{
  priority_queue< A , vector<A> >  t;
  return 0;
}

If < < is overloaded in the class (overloading > will cause compilation errors. Mathematically speaking, only overloading < is enough), there is no need to specify which cmp the queue uses. If it is specified as the maximum heap, the third parameter (the position of cmp) can be written as less, and the minimum heap can be written as greater in one step.
Simply put, the template parameters in STL need to fill in the class name. Either overload '<' in the class or write a structure overload '()' outside the class, and then fill in the template parameters

To sum up, the effect of cmp return value in sort is different from that of queue and qsort (it means that if the same large value comes first, sort should use greater than, while queue and sort use less than)

Added by lajollabob on Wed, 09 Mar 2022 15:10:32 +0200