C++实现CListEx类派生MFC中Clist链表类实现表内表外排序的扩展功能

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

表内排序将改变原有的排列顺序,表外排序不会改变

发布了21 篇原创文章 · 获赞 20 · 访问量 2973

猜你喜欢

转载自blog.csdn.net/weixin_42844163/article/details/104170124