top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
いがぴょんの日記v1 (旧称: ある開発者の日記) から移植しました。
関数テンプレートを利用して改良してみました。関数テンプレートって、すっごく便利ですね(^^) 今後どんどん活用しようと思いました。関数テンプレートを使って作成したライブラリを、下記に添付します。
// 挿入ソート関数テンプレートライブラリ for MFC
//
// 作成 (1997/07/22) by t.iga
#ifndef _BBSORT_H_
#define _BBSORT_H_
// CListのアイテムを挿入ソートします。
template <class TYPE>
void funcInsertSortCList(
CList<TYPE,TYPE>* plistTest,
int (__cdecl *compare)(const void *elem1,const void *elem2))
{
// 挿入ソートの注目要素
TYPE keyitem;
for(POSITION posLoopOut=plistTest->GetHeadPosition();
posLoopOut;
plistTest->GetNext(posLoopOut))
{
// 挿入ソートの注目要素を取り出します。
keyitem=plistTest->GetAt(posLoopOut);
POSITION posPrev=posLoopOut;
POSITION posLoopIn=posLoopOut;
for(plistTest->GetPrev(posLoopIn);
posLoopIn;
plistTest->GetPrev(posLoopIn))
{
TYPE& lookitem=plistTest->GetAt(posLoopIn);
// 比較を行います。
if(compare(&lookitem,&keyitem)<=0)
{
break;
}
// 注目要素より大きいものを、右に移動します。
plistTest->GetAt(posPrev)=lookitem;
// 以前のポジションを記憶しておきます。
posPrev=posLoopIn;
}
// 挿入ソートの注目要素を格納します。
plistTest->GetAt(posPrev)=keyitem;
}
}
// CArrayのアイテムを挿入ソートします。
template <class TYPE>
void funcInsertSortCArray(
CArray<TYPE,TYPE>* parrayTest,
int (__cdecl *compare)(const void *elem1,const void *elem2))
{
int iMaxCount=parrayTest->GetSize();
// 挿入ソートの注目要素
TYPE keyitem;
for(int iLoopOut=1;iLoopOut<iMaxCount;iLoopOut++)
{
// 挿入ソートの注目要素を取り出します。
keyitem=(*parrayTest)[iLoopOut];
for(int iLoopIn=iLoopOut-1;iLoopIn>=0;iLoopIn--)
{
// 比較を行います。
if(compare(&((*parrayTest)[iLoopIn]),&keyitem)<=0)
{
break;
}
// 注目要素より大きいものを、右に移動します。
(*parrayTest)[iLoopIn+1]=(*parrayTest)[iLoopIn];
}
// 挿入ソートの注目要素を格納します。
(*parrayTest)[iLoopIn+1]=keyitem;
}
}
#endif _BBSORT_H_
// CList
#include <afxtempl.h>
#include "bbsort.h"
typedef struct tagTESTITEM
{
int m_iA;
long m_lB;
}TestItem;
// 比較関数:qsort()の場合と ほぼ同様の実装になっています。
int __cdecl compareFunc(const void *elem1, const void *elem2 )
{
TestItem* pElem1=(TestItem*)elem1;
TestItem* pElem2=(TestItem*)elem2;
if(pElem1->m_lB>pElem2->m_lB)
{
return 1;
}
return (-1);
}
void CMainFrame::OnTestTestgo()
{
// TODO: この位置にコマンド ハンドラ用のコードを追加してください
CList<TestItem,TestItem> listTest;
TestItem test;
test.m_lB=1;
listTest.AddTail(test);
test.m_lB=3;
listTest.AddTail(test);
test.m_lB=5;
listTest.AddTail(test);
test.m_lB=6;
listTest.AddTail(test);
test.m_lB=4;
listTest.AddTail(test);
test.m_lB=2;
listTest.AddTail(test);
funcInsertSortCList(&listTest,compareFunc);
for(POSITION posLoop=listTest.GetHeadPosition();
posLoop;
listTest.GetNext(posLoop))
{
TestItem& item=listTest.GetAt(posLoop);
CString strFormat;
strFormat.Format("%ld",item.m_lB);
MessageBox(strFormat);
}
}
void CMainFrame::OnTestTestgo2()
{
// TODO: この位置にコマンド ハンドラ用のコードを追加してください
CArray<TestItem,TestItem> arrayTest;
TestItem test;
test.m_lB=1;
arrayTest.Add(test);
test.m_lB=3;
arrayTest.Add(test);
test.m_lB=5;
arrayTest.Add(test);
test.m_lB=6;
arrayTest.Add(test);
test.m_lB=4;
arrayTest.Add(test);
test.m_lB=2;
arrayTest.Add(test);
funcInsertSortCArray(&arrayTest,compareFunc);
for(long lLoop=0;
lLoop<arrayTest.GetSize();
lLoop++)
{
CString strFormat;
strFormat.Format("%ld",arrayTest[lLoop].m_lB);
MessageBox(strFormat);
}
}