这里实现了两种排序:链表内部排序和链表外部排序:
链表外部排序不会真实改变数据顺序:
//在链表外部进行排序,不会直接影响到链表内的数据排序;实现方法是 申请一段对空间数组,用来存放指针,这些指针,指向
//链表内的数据,排序的时候根据链表内数据的大小只要交换指针的位置就可以;比如链表内数据为 55 22 33 11 44;那么申请
//一段堆空间数组 p[] 数组里面存放指针 p[0]指向55 p[1]指向22, p[2]指向33,p[3]指向11,p[4]指向44,采用选择排序进行排序
//第一轮找到最小的11,那么就把p[0] 与 p[3]相互对调,p[0]指向11,p[3]指向55,所以链表内部数据并没有变化,
ListEx.h
#pragma once
#include<afxtempl.h>
template<typename TYPE,typename TYPE_ARG>
class CListEx:public CList<TYPE,TYPE_ARG>
{
public:
CListEx(void){}
~CListEx(void){}
public:
typedef bool (*SORT_FUNC)(const TYPE& t1,const TYPE& t2);//声明函数指针
//在链表内部进行排序,直接影响链表数据的排序
void SortInList(SORT_FUNC byFunc)
{
CNode* p = m_pNodeHead,*q,*pMin;
while (p)
{
q = pMin = p;
q = q->pNext;
while (q)
{
if (byFunc(q->data,pMin->data))
{
pMin = q;
}
q = q->pNext;
}
if (pMin!=p)
{
TYPE t = pMin->data;
pMin->data = p->data;
p->data = t;
}
p = p->pNext;
}
}
//在链表外部进行排序,不会直接影响到链表内的数据排序;实现方法是 申请一段对空间数组,用来存放指针,这些指针,指向
//链表内的数据,排序的时候根据链表内数据的大小只要交换指针的位置就可以;比如链表内数据为 55 22 33 11 44;那么申请
//一段堆空间数组 p[] 数组里面存放指针 p[0]指向55 p[1]指向22, p[2]指向33,p[3]指向11,p[4]指向44,采用选择排序进行排序
//第一轮找到最小的11,那么就把p[0] 与 p[3]相互对调,p[0]指向11,p[3]指向55,所以链表内部数据并没有变化,
POSITION* SortOutList(SORT_FUNC byFunc)
{
int n = m_nCount;
CNode* * ps = new CNode*[n+1];//二级指针,存放的是指针
CNode* p = m_pNodeHead;
ps[n] = NULL;
int i = 0;
while (i < n)
{
ps[i] = p;
p = p->pNext;
++i;
}
i = 0;
int j = 0,nMin = 0;
while (i < n)
{
nMin = i;
j = i + 1;
while (j<n)
{
if (byFunc(ps[j]->data,ps[nMin]->data))
{
nMin = j;
}
++j;
}
if (nMin!= i)
{
CNode* t = ps[nMin];
ps[nMin] = ps[i];
ps[i] = t;
}
++i;
}
return (POSITION*)ps;
}
};
main.cpp
// CListEx.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ListEx.h"
#include <iostream>
using namespace std;
bool Comp(const int& i, const int& j)
{
return i<j;
}
int _tmain(int argc, _TCHAR* argv[])
{
CListEx<int,int> m_list;
int a[] = {2,5,1,4,7,0};
int i = 0;
while (a[i])
{
m_list.AddTail(a[i++]);
}
POSITION pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
/*
//采用在链表内部排序
m_list.SortInList(Comp);
cout<<"在链表类内部排序:"<<endl;
pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
*/
//采用在链表外部进行排序,不真实影响链表内部的数据排序
POSITION* ps = m_list.SortOutList(Comp);
cout<<"类外部的排序:"<<endl;
i = 0;
while (ps[i])
{
cout<<m_list.GetAt(ps[i])<<endl;
++i;
}
delete[]ps;
cout<<"输出排序后链表内的数据:"<<endl;
pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
getchar();
return 0;
}
// CListEx.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ListEx.h"
#include <iostream>
using namespace std;
bool Comp(const int& i, const int& j)
{
return i<j;
}
int _tmain(int argc, _TCHAR* argv[])
{
CListEx<int,int> m_list;
int a[] = {2,5,1,4,7,0};
int i = 0;
while (a[i])
{
m_list.AddTail(a[i++]);
}
POSITION pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
/*
//采用在链表内部排序
m_list.SortInList(Comp);
cout<<"在链表类内部排序:"<<endl;
pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
*/
//采用在链表外部进行排序,不真实影响链表内部的数据排序
POSITION* ps = m_list.SortOutList(Comp);
cout<<"类外部的排序:"<<endl;
i = 0;
while (ps[i])
{
cout<<m_list.GetAt(ps[i])<<endl;
++i;
}
delete[]ps;
cout<<"输出排序后链表内的数据:"<<endl;
pos = m_list.GetHeadPosition();
while (pos)
{
cout<<m_list.GetNext(pos)<<endl;
}
getchar();
return 0;
}
采用链表内部排序后再打印一次链表内的数据;发现数据顺序已经发生了改变
采用链表外部排序后再打印依次链表内的数据;发现数据顺序没有发生改变!