tsc_IQSort

This is an interface for sorting any kind of object.  This isn't strictly an interface since the implementation of the sort is part of the class.

The small example below illustrates how to use IQSort.  This is simply a matter of subclassing from the IQSort and implementing these two abstract methods:

virtual int QSortCompare (int elem1, int elem2, int param) = 0;
elem1 and elem2 are the indices of the items to be compared, and param is the param argument passed to the QSort.
Return -1 if elem1 precedes elem2 in the sorted sequence, 0 if they are equivalent, or 1 if elem1 follows elem2.

virtual void QSortSwap (int elem1, int elem2, int param) = 0;
Your override should swap the two elements.

Note that the sort is not stable.  That is, the sequence of equal items is indeterminate - and for this reason it is advisable to compare on one or more subfields when the primary sort keys are equal.

void QSort (int elementCount, int param);
Call this method to perform the sort.  param may be used to pass a value to the QSortSwap and QSortCompare methods.

Example: Sorting a list of items derived from tsc_Object

struct Quake : public tsc_Object 

{

    Quake (tsc_String place, double strength) 

    { 

        Place = place;

        Strength = strength;

    } 


    virtual tsc_String ToString() const

    { 

        return tsc_String::Format ("%s (%#3.1f)", Place, Strength);

    }   

    

    tsc_String  Place;

    double      Strength;

};


class Quakes : public tsc_Object, protected tsc_IQSort

public: 

    Quakes() : _quakes(true)

    {} 


    void Add (Quake* q) 

    { 

        _quakes.Append (q);

    } 


    void SortByStrengthDescending() 

    { 

        tsc_IQSort::QSort(_quakes.Count(), 0);

    }


    tsc_String ToString () 

    { 

        tsc_String s;

        for (int ix = 0; ix < _quakes.Count(); ix++) 

        { 

            s += _quakes[ix]->ToString() + tsc_SurveyCore::NewLine();

        } 

        return s;        

    } 


private: 

    int QSortCompare (int e1, int e2, int p) 

    { 

        Quake* q1 = (Quake*)_quakes[e1];

        Quake* q2 = (Quake*)_quakes[e2];

        if (q1->Strength < q2->Strength) return 1;

        if (q1->Strength > q2->Strength) return -1;

        return q1->Place.Compare(q2->Place);     // Equal strengths, sort by place name.

        } 


        void QSortSwap (int e1, int e2, int p)

        { 

            _quakes.Swap(e1, e2);

        } 


        tsc_List _quakes;

};


void ListQuakes()

{

    Quakes  mq;

    mq.Add (new Quake("Valparaiso, Chile", 9.2));

    mq.Add (new Quake("Tohoku, Japan", 9.1));

    mq.Add (new Quake("Chittagong, Bangladesh", 8.8));

    mq.Add (new Quake("Cascadia", 9.0));

    mq.Add (new Quake("Arica", 9.0));

    mq.Add (new Quake("Kamchatka", 9.0));

    mq.Add (new Quake("Sumatra", 9.2));

    mq.Add (new Quake("Alaska", 9.5));

    mq.Add (new Quake("Valdivia, Chile", 9.5));

    mq.SortByStrengthDescending ();

    tsc_MessageBox::Show ("Biggest Quakes", mq.ToString());

}


 The above example produced this output (though it's different now, since we updated the earthquake list):