基于回调,支持快速排序的 CArray 模板类





1.00/5 (1投票)
2000年10月19日

74383

1006
本文介绍了一个基于回调,支持快速排序的 CArray 模板类。
引言
本文基于 Martin Ziacek 的 CQArray 模板类 和 Russell Robinson 的 COCArray 模板类。请在继续阅读之前阅读他们的文章,我只会提及修改的部分。
动机
我在我的项目中使用了大量的列表(通常是 ListView),包含大量的记录。如果你曾经尝试将大约 200,000 行放入 ListView,你一定知道那是一场噩梦!在列表中移动非常慢,内存分配很高,而且如果你想检索任何数据(例如,用户双击了该行),你必须将你的字符串转换为“可用”的数据类型。所有者数据列表要快得多,但是如果你想实现一个可排序的所有者数据列表,你必须处理排序。这就是我需要这个 CArrayEx
类 的原因。
实现
使用 CArrayEx
类似于使用 CArray
,但你只需要在声明中指定 1 个参数
typedef struct { int index; float fSomeFloat; TCHAR SomeString[128]; } UserType; CArrayEx<UserType> m_Data;
其中 UserType
是用户定义的 结构体
。
为了完成排序,你必须在想要进行排序的类中声明一个静态成员函数。例如,一个 CDocument
派生类(在基于 Doc/View 的应用程序中)。如果你有了这个过程,那么你必须告诉数组使用该过程进行项目比较,然后通过指定列号和排序方向来调用 QuickSort
。
CDocument
派生部分如下所示
(在 .h 文件中:)
static int CompareUserType(int iColumn, const UserType& udtLeft, const UserType& udtRight);
(在 .cpp 文件中:)
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); }
很简单,不是吗?
最后的寄语
在示例程序中(最初来自 Martin 的文章),你可以指定项目计数以及对 int
数组和 UserType
数组的排序类型。
我希望这个类能为一些人节省时间。
没有版权以及通常的声明。:-)
欢迎提出改进建议! 免费使用此代码,但请自行承担风险。