1.CListEx
//ListEx.h
#pragma once
#include <afxtempl.h>
template<class TYPE, class ARG_TYPE = const TYPE&>
class CListEx :public CList<TYPE, ARG_TYPE>
{
public:
typedef bool(*SORT_FUNC)(const TYPE& t1, const TYPE& t2);
//表内无参排序函数
void SortIn()
{
CNode* pos = m_pNodeHead;
while (pos)
{
CNode* q = pos->pNext, *m = pos;
while (q)
{
if (q->data < m->data)
m = q;
q = q->pNext;
}
if (pos != m)
{
TYPE tmp = pos->data;
pos->data = m->data;
m->data = tmp;
}
pos = pos->pNext;
}
}
//表内有参(需要指定回调函数)排序函数
void SortIn(SORT_FUNC byFunc)
{//链表内排序
CNode* pos = m_pNodeHead;
while (pos)
{
CNode* q = pos->pNext, *m = pos;
while (q)
{
if ((byFunc(q->data, m->data)))
m = q;
q = q->pNext;
}
if (pos != m)
{
TYPE tmp = pos->data;
pos->data = m->data;
m->data = tmp;
}
pos = pos->pNext;
}
}
//表外有参(需要指定回调函数)排序函数
//返回指定POSITION数组的指针,用于打印数据
POSITION* SortOut(SORT_FUNC byFunc)
{//链表外排序
POSITION *ps = new POSITION[m_nCount+1];
POSITION pos = GetHeadPosition();
int i = 0;
while (ps[i++] = pos)
GetNext(pos);
i = 0;
while (i < m_nCount - 1)
{
int j = i + 1, m = i;
while (j < m_nCount)
{
if (byFunc(GetAt(ps[j]), GetAt(ps[m])))
m = j;
++j;
}
if (i != m)
{
POSITION tmp = ps[i];
ps[i] = ps[m];
ps[m] = tmp;
}
++i;
}
return ps;
}
//表外无参排序函数
//返回指定POSITION数组的指针,用于打印数据
POSITION* SortOut()
{//链表外排序
POSITION *ps = new POSITION[m_nCount + 1];
POSITION pos = GetHeadPosition();
int i = 0;
while (ps[i++] = pos)
GetNext(pos);
i = 0;
while (i < m_nCount - 1)
{
int j = i + 1, m = i;
while (j < m_nCount)
{
if (GetAt(ps[j]) < GetAt(ps[m]))
m = j;
++j;
}
if (i != m)
{
POSITION tmp = ps[i];
ps[i] = ps[m];
ps[m] = tmp;
}
++i;
}
return ps;
}
};
2.代码测试
2.1表内排序有参测试
// CListEx.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include "ListEx.h"
#include <iostream>
using namespace std;
typedef struct
{
int nNumb;
char sName[20];
float fScore;
}Data;
//定义回调函数(三种排序规则)
bool ByNumb(const Data& d1, const Data& d2)
{
return d1.nNumb < d2.nNumb;
}
bool ByName(const Data& d1, const Data& d2)
{
return strcmp(d1.sName, d2.sName) < 0;
}
bool ByScore(const Data& d1, const Data& d2)
{
return d1.fScore > d2.fScore;
}
//数据打印函数
void Print(CListEx<Data>& list)
{
POSITION pos = list.GetHeadPosition();
while (pos)
{
Data data = list.GetNext(pos);
cout << data.nNumb << "\t" << data.sName << "\t" << data.fScore << endl;
}
}
int main()
{
CListEx<Data> list;
Data d1[] = {
{1002, "张三", 100},
{1001, "李四", 96.5},
{1006, "Alice", 87.5},
{1009, "孙彬", 86},
{1004, "王五", 92.5}
};
int i = 0;
while (i < 5)
list.AddTail(d1[i++]);
cout << "排序前:" << endl;
Print(list);
cout << "按照学号排序:" << endl;
list.SortIn(ByNumb);
Print(list);
cout << "按照姓名排序:" << endl;
list.SortIn(ByName);
Print(list);
cout << "按照成绩排序:" << endl;
list.SortIn(ByScore);
Print(list);
return 0;
}
运行结果:
按照学号排序:
1001 李四 96.5
1002 张三 100
1004 王五 92.5
1006 Alice 87.5
1009 孙彬 86
按照姓名排序:
1006 Alice 87.5
1001 李四 96.5
1009 孙彬 86
1004 王五 92.5
1002 张三 100
按照成绩排序:
1002 张三 100
1001 李四 96.5
1004 王五 92.5
1006 Alice 87.5
1009 孙彬 86
2.1表外排序有参测试
// CListEx.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ListEx.h"
#include <iostream>
using namespace std;
typedef struct
{
int nNumb;
char sName[20];
float fScore;
}Data;
//回调函数(排序规则)
bool ByNumb(const Data& d1, const Data& d2)
{
return d1.nNumb < d2.nNumb;
}
bool ByName(const Data& d1, const Data& d2)
{
return strcmp(d1.sName, d2.sName) < 0;
}
bool ByScore(const Data& d1, const Data& d2)
{
return d1.fScore > d2.fScore;
}
//打印数据
void PrintOut(CListEx<Data>& list, POSITION* ps)
{
int i = 0;
while (ps[i])
{
Data data = list.GetAt(ps[i]);
cout << data.nNumb << "\t" << data.sName << "\t" << data.fScore << endl;
++i;
}
}
int main()
{
CListEx<Data> list;
Data d1[] = {
{1002, "张三", 100},
{1001, "李四", 96.5},
{1006, "Alice", 87.5},
{1009, "孙彬", 86},
{1004, "王五", 92.5}
};
int i = 0;
while (i < 5)
list.AddTail(d1[i++]);
POSITION* ps = NULL;
cout << "排序前:" << endl;
Print(list);
cout << "按照学号排序:" << endl;
ps = list.SortOut(ByNumb);
PrintOut(list, ps);
cout << "按照姓名排序:" << endl;
ps = list.SortOut(ByName);
PrintOut(list, ps);
cout << "按照成绩排序:" << endl;
ps = list.SortOut(ByScore);
PrintOut(list, ps);
cout << "排序后:" << endl;
Print(list);
return 0;
}
运行结果:
排序前:
1002 张三 100
1001 李四 96.5
1006 Alice 87.5
1009 孙彬 86
1004 王五 92.5
按照学号排序:
1001 李四 96.5
1002 张三 100
1004 王五 92.5
1006 Alice 87.5
1009 孙彬 86
按照姓名排序:
1006 Alice 87.5
1001 李四 96.5
1009 孙彬 86
1004 王五 92.5
1002 张三 100
按照成绩排序:
1002 张三 100
1001 李四 96.5
1004 王五 92.5
1006 Alice 87.5
1009 孙彬 86
排序后:
1002 张三 100
1001 李四 96.5
1006 Alice 87.5
1009 孙彬 86
1004 王五 92.5
表内排序将改变原有的排列顺序,表外排序不会改变