Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Callback based, Quicksort enabled CArray template class

0.00/5 (No votes)
18 Oct 2000 1  
This article presents a callback based, QuickSort enabled CArray template class.

Sample Image - ArrayEx.jpg

Introduction

This article is based on Martin Ziacek's CQArray template class and Russell Robinson's COCArray template class. Please read their article before going on, I will mention the modifications only.

Motivation

I'm using a lot of lists (typically listviews) in my projects, with a lot of records. If you ever tried to place about 200.000 rows into a listview, you must know it's a nightmare! Moving in the list is very-very slow, memory allocation is very high, and if you want to retrieve any data (because the user has double clicked the row, for example), you have to convert your string to a "usable" data type. The owner data lists are much faster, but if you like to implement a sortable owner data list, you have to deal with the sorting. That's why I needed this CArrayEx class.

Implementation

Using CArrayEx is similar to using CArray but you have to specify only 1 parameter in the declaration:

typedef struct
{
    int   index;
    float fSomeFloat;
    TCHAR SomeString[128];
} UserType;

CArrayEx<UserType>    m_Data;

where UserType is a user defined struct.

For the sorting to be done, you have to declare a static member function in your class where you want the sorting to be done. For example, a CDocument derived class (in the case of a Doc/View based application). If you have the procedure, then you have to tell the array to use that procedure for item compare, and then call QuickSort by specifying the column number and sort direction.

The CDocument derived part will look like this:

(in the .h file:)

static int CompareUserType(int iColumn, const UserType& udtLeft, 
              const UserType& udtRight);

(in the .cpp file:)

int CMyDocument::CompareUserType(int iColumn, 
    const UserType& udtLeft, const UserType& udtRight)
{
    int iResult = 0;

    switch(iColumn)
    {
    case 1:
        if (udtLeft.index==udtRight.index)
            iResult = 0;
        else if (udtLeft.index&ludtRight.index)
            iResult = -1;
        else iResult = 1;
        break;
    case 2:
        if (udtLeft.fSomeFloat==udtRight.fSomeFloat)
            iResult = 0;
        else if (udtLeft.fSomeFloat<udtRight.fSomeFloat)
            iResult = -1;
        else iResult = 1;
        break;
    case 3:
        iResult = strcmp((char*)udtLeft.SomeString, 
                          (char*)udtRight.SomeString);
        break;
    }

    return iResult;
}

void CMyDocument::DoSort()
{
    m_Data.SetCompareFunction(CompareUserType);

    // Sort on index field of the structure, ascending direction

    m_Data.QuickSort(1, TRUE);
}

It's easy, isn't it?

Final words

In the sample program (which was originally from Martin's article), you can specify an item count, and the type of sorting on an int array and on a UserType array.

I hope this class can save some time for a few people.

There is no copyright and the (un)usual stuff. :-)

Any improvements are welcome! Use this code free, but at your own risk.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here