Offipalsta.COM  

Palaa takaisin   Offipalsta.COM > Linkit muihin palveluihin > Elävä Arkisto > Programming > C/C++
Rekisteröidy Offiblogit Yhteisö Kalenteri Viestit tänään Haku

C/C++ C/C++, MSVC, GCC, G++, Borland C++ Builder

 
 
Työkalut Etsi tästä viestiketjusta Näkymä
  #1  
Vanha 28.09.2002, 08:28
Lars
Guest
 
Viestit: n/a
Perusasetus

Sortattava CObArray


// SortableObArray.h
/////////////////////////////////////////////////////////////////////

class CSortableObArray : public CObArray
{
public:
void Sort(int(*CompareFunc)(CObject* pFirst, CObject* pSecond));
void Sort(int iStartPos, int iElements, int(*CompareFunc)(CObject* pFirst, CObject* pSecond));
};


template< class TYPE >
class CTypedSortableObArray : public CSortableObArray
{
public:
// Accessing elements
TYPE GetAt(int nIndex) const
{ return (TYPE)CSortableObArray::GetAt(nIndex); }
TYPE& ElementAt(int nIndex)
{ return (TYPE&)CSortableObArray::ElementAt(nIndex); }
void SetAt(int nIndex, TYPE ptr)
{ CSortableObArray::SetAt(nIndex, ptr); }

// Potentially growing the array
void SetAtGrow(int nIndex, TYPE newElement)
{ CSortableObArray::SetAtGrow(nIndex, newElement); }
int Add(TYPE newElement)
{ return CSortableObArray::Add(newElement); }
int Append(const CTypedPtrArray< CSortableObArray, TYPE >& src)
{ return CSortableObArray::Append(src); }
void Copy(const CTypedPtrArray< CSortableObArray, TYPE >& src)
{ CSortableObArray::Copy(src); }

// Operations that move elements around
void InsertAt(int nIndex, TYPE newElement, int nCount = 1)
{ CSortableObArray::InsertAt(nIndex, newElement, nCount); }
void InsertAt(int nStartIndex, CTypedSortableObArray< TYPE >* pNewArray)
{ CSortableObArray::InsertAt(nStartIndex, pNewArray); }

// overloaded operator helpers
TYPE operator[](int nIndex) const
{ return (TYPE)CSortableObArray:perator[](nIndex); }
TYPE& operator[](int nIndex)
{ return (TYPE&)CSortableObArray:perator[](nIndex); }

void Sort( int(*CompareFunc)(TYPE pFirstObj, TYPE pSecondObj) )
{ CSortableObArray::Sort((int(*)(CObject*,CObject*)) CompareFunc); }
void Sort( int iStartPos, int iElements, int(*CompareFunc)(TYPE pFirstObj, TYPE pSecondObj) )
{ CSortableObArray::Sort(iStartPos, iElements, (int(*)(CObject*,CObject*))CompareFunc); }
};



// SortableObArray.cpp
///////////////////////////////////////////////////////////////////

#define STRIDE_FACTOR 3

void CSortableObArray::Sort(int(*CompareFunc)(CObject* pFirst, CObject* pSecond))
{
// CompareFunc is expected to return a positive integer if pFirstObj
// should follow pSecondObj (is greater than)

// Uses Shell Sort

// Basically it does a bunch of smaller insertion sorts than insertion sorts the
// whole thing. Insertion sorting is much faster on a list that is already
// mostly sorted.

// ** NOTE: Because GetSize() is called to retrieve the number of elements, you should
// call SetSize() with the number of valid elements. An alternative is
// shown in the sort function below.

ASSERT_VALID(this);

BOOL bFound;
int iElements = GetSize();
int iInner,iOuter,iStride = 1;
CObject *pTmp;

while (iStride <= iElements)
iStride = iStride * STRIDE_FACTOR + 1;

while (iStride > (STRIDE_FACTOR - 1))
{
iStride = iStride / STRIDE_FACTOR;
for (iOuter = iStride; iOuter < iElements; iOuter++)
{
bFound = 0;
iInner = iOuter - iStride;
while ((iInner >= 0) && !bFound)
{
if (CompareFunc(m_pData[iInner+iStride],m_pData[iInner]) < 0)
{
pTmp = m_pData[iInner+iStride];
m_pData[iInner+iStride] = m_pData[iInner];
m_pData[iInner] = pTmp;
iInner -= iStride;
}
else
bFound = 1;
}
}
}
}

void CSortableObArray::Sort(int iStartPos, int iElements, int(*CompareFunc)(CObject* pFirst, CObject* pSecond))
{
// This variation allows you to sort only a portion of the array

ASSERT_VALID(this);
ASSERT( iStartPos >= 0 && iStartPos <= GetUpperBound() );
ASSERT( GetSize() - iStartPos >= iElements );

BOOL bFound;
int iInner,iOuter,iStride = 1;
CObject *pTmp;
CObject **pData = &m_pData[iStartPos];

while (iStride <= iElements)
iStride = iStride * STRIDE_FACTOR + 1;

while (iStride > (STRIDE_FACTOR - 1))
{
iStride = iStride / STRIDE_FACTOR;
for (iOuter = iStride; iOuter < iElements; iOuter++)
{
bFound = 0;
iInner = iOuter - iStride;
while ((iInner >= 0) && !bFound)
{
if (CompareFunc(pData[iInner+iStride],pData[iInner]) < 0)
{
pTmp = pData[iInner+iStride];
pData[iInner+iStride] = pData[iInner];
pData[iInner] = pTmp;
iInner -= iStride;
}
else
bFound = 1;
}
}
}
}



// Usage
//////////////////////////////////////////////////////////

// Create a CObject based class
class CMyObject : public CObject
{
public:
CString name;
static int CompBackward(CMyObject* pFirstObj, CMyObject* pSecondObj)
{
return -lstrcmp((LPCTSTR)pFirstObj->name,(LPCTSTR)pSecondObj->name);
}
};

// Create an array object
CTypedSortableObArray< CMyObject* > array;

array.SetSize(10);

// Fill the array with a bunch of objects
for (int i=0; i < 10; i++)
{
CMyObject * pObj = new CMyObject;
pObj->name.Format("Object #%d",i);
array[i] = pObj;
}

// Sort the array
array.Sort(CMyObject::CompBackward);

// Display the contents of the now sorted array
for (int i=0; i < 10; i++)
{
TRACE1("%s\n",array[i]->name);
}

Varmaan kannattaa jysäyttää beautifierin läpi ennen käyttöä

--
Lars

 

Käyttäjiä lukemassa tätä viestiketjua: 1 (0 jäsentä and 1 vierasta)
 

Pikalinkit


Sivu luotu: 15:28 (GMT +2).