20

C++ Sorting Array Class

I have an array object that record the following..

This is at classone.h

ClassOne
{
string name;
int data;
float valueData;
}

and the constructor are created at classone.cpp

At main.cpp I created ClassOne Array of Size 10

#include "classone.h"

ClassOne cone[10];

Next is i recorded several value to the object

and now ClassOne got 3 objects

cone[0]
name = "hello"
data = 1
valueData = 20

cone[1]
name = "panda"
data = 2
valueData = 15

cone[2]
name = "joe"
data = 3
valueData = 25

What i want to achieve is do a sort that can rearrange this array by valueData highest ascending form so.. it will be

cone[2] then cone[0] then cone[1] ..

but the issue if i use bubble sort , i tried google and find some, they are sorting by e.g int a[]={9,6,5,23,2,6,2,7,1,8};

but i wanna sort by class array object. and re-arrange the value together , how do i achieve this.

So when i cout it will be

-- Highest to lowest --
1) Name: Joe , Data = 3, Value =25
2) Name: Hello , Data =1 , Value = 20
3) Name: Panda, Data = 2, Value = 15

Thanks for all help and guide!!

baoky chen
  • 799
  • 2
  • 11
  • 20

6 Answers6

26

The easiest way is to use the standard library:

#include <algorithm>

std::sort(cone, cone + 10,
          [](ClassOne const & a, ClassOne const & b) -> bool
          { return a.value < b.value; } );

If you're willing to define a comparison operator globally, you don't even need the lambda:

bool operator<(ClassOne const & a, ClassOne const & b)
{
    return a.value < b.value;
}

std::sort(cone, cone + 10);

Or you could make the comparator a member function. Or you could give the comparator function a custom name and pass that as the third argument of sort. This might be a good idea in the case where the comparison is specific to your situation and not "natural":

bool ValueCmp(ClassOne const & a, ClassOne const & b)
{
    return a.value < b.value;
}

std::sort(cone, cone + 10, ValueCmp);

The last version is useful if you don't have C++11 support (for lambdas, as in the first case), or if you want to reuse the comparator in multiple different situations.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    I not sure how to apply sort to my object.. i tried your example but got some errors.. – baoky chen Oct 10 '12 at 16:05
  • @baokychen: I had misspelled the class name. Refresh the page and try again. It should work. – Kerrek SB Oct 10 '12 at 16:06
  • For consistency and clarity, I suggest using the address-of operator `&` to form function pointers, instead of the implicit conversion from function to function pointer. – Ben Voigt Oct 10 '12 at 16:10
  • I tried to compare a.value < b.value and it say float ClassOne:: value is private – baoky chen Oct 10 '12 at 16:11
  • 1
    And so it is. Make the comparison function either a static member or a friend of the class. – Ben Voigt Oct 10 '12 at 16:12
  • Or change `class` to `struct`. That might be the simplest quick fix. – Kerrek SB Oct 10 '12 at 16:15
  • what if the ClassOne is another cpp file which i include, and my main.cpp is the place where execute it . where should i place ValueCmp and how do i change the formula – baoky chen Oct 10 '12 at 16:15
  • 2
    @baokychen: If you don't understand the concept of public and private members, then you are getting ahead of yourself. You should really have the basics of classes out of the way before you try to do anything like sorting objects. – Benjamin Lindley Oct 10 '12 at 16:25
  • sorry Benjamin Lindley, i still not sure how to get going.. as my ClassOne is a object from ClassOne.cpp & ClassOne.h , i am using it at main.cpp then record value.. but now i need do sorting and then display the result with highest valueData first, showing the name & int data that comes with that float valueData – baoky chen Oct 10 '12 at 16:26
  • 1
    @baokychen: Yes, I understand what you're trying to do, and I understand that you are not sure how to get going. I'm saying that you need to learn to crawl before you can walk. Where crawl="a basic understanding of how classes work", and walk="sorting class objects". What you need is a basic beginner's book. Here's a list: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Benjamin Lindley Oct 10 '12 at 16:32
11

Use std::sort and a suitable sort function/functor:

bool comp(const ClassOne& lhs, const ClassOne& rhs)
{
  return lhs.valueData < rhs.valueData;
}

std::sort(cone, cone+10, comp);

or, in C++11,

std::sort(std::begin(cone), std::end(cone), comp);
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • I saw your guide on standard library, how do i use it with my cone object? – baoky chen Oct 10 '12 at 16:02
  • @baokychen just as above. You don't have a cone object, you have an array of `ClassOne` objects called `cone??. – juanchopanza Oct 10 '12 at 16:04
  • For consistency and clarity, I suggest using the address-of operator `&` to form function pointers, instead of the implicit conversion from function to function pointer. – Ben Voigt Oct 10 '12 at 16:11
9

You can make a struct that implements the operator < method that std::sort in the <algorithm> header uses to sort iterated items.

struct One {
string name;
int data;
float valueData;

bool operator < (const one &a) const{
return valueData <a.valueData;
}

};

then all you have to do is to make an array of this struct and sort it using the sort function

quine
  • 982
  • 1
  • 12
  • 20
DaRkViRuS
  • 99
  • 1
  • 7
3

Look at your Bubble sort source. At some point, it will be comparing one int to another, probably with either the less than operator (<) or the greater than operator (>). That's where the sort function determines the relative order of those two items. By repeating that comparison many times, the sort function is able to determine the total order of the collection.

You need to replace that operation with your own comparison function. A function that takes two objects of your class, and returns true if the first should be considered less than the second, false if the second should be considered less than the first, and false if they should be considered equivalent.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
2

You must define a comparison operator for your class. How you determine whether one object is less than another isn't clear from your question.

Adam
  • 406
  • 3
  • 9
0

Try this ... ....

     void ClassOne::sort(ClassOne *obj,int n)       
     {
      ClassOne temp;
      int i, j;
      for (i = 0; i < n; i++)
      for (j = n - 1; j > i; j--)
        if (obj[j].valueData <obj[j - 1].valueData )
           {
            temp = obj[j];
            obj[j] = obj[j - 1];
            obj[j - 1] = temp;
         }
         }
     ...
      int main()
      {
     ClassOne obj[3],a;
        for(int i=0;i<3;i++)
         obj[i].readdata();
        a.sort(obj,3);
        ...
  }