602 lines
8.8 KiB
C++
602 lines
8.8 KiB
C++
#pragma once
|
|
#include "SHTable.h"
|
|
#include "SHQuene.h"
|
|
|
|
template<class T> class SHArray
|
|
{
|
|
public:
|
|
|
|
SHArray(long size = 0);
|
|
SHArray(const SHArray<T>& array);
|
|
SHArray(const SHTable<T>& table);
|
|
SHArray<T>& operator = (const SHArray<T>& array);
|
|
virtual ~SHArray();
|
|
|
|
//space
|
|
void Realloc(long newLength,bool bCopy = true);
|
|
|
|
//attribute
|
|
bool IsValidIndex(long index) const;
|
|
bool IsEmpty() const;
|
|
long GetLength() const;
|
|
long GetLastIndex() const;
|
|
bool operator == (const SHArray<T>&array) const;
|
|
bool operator != (const SHArray<T>&array) const;
|
|
|
|
//random visit
|
|
T& operator[](long index);
|
|
const T& GetAt(long index) const;
|
|
void SetAt(long index,const T&t);
|
|
T* GetBuffer() const;
|
|
|
|
//insert/delete
|
|
void Insert(long index,const T&t);
|
|
void InsertHead(const T&t);
|
|
long AddTail(const T&t);
|
|
void Del(long index);
|
|
void DelFirst();
|
|
void DelTail();
|
|
void Clear();
|
|
|
|
//search
|
|
long Find(const T&t,long from = 0,long to = -1) const;
|
|
long Find(const T&t,SHQuene<long>&quene,long from = 0,long to = -1) const;
|
|
long FindOrAddTail(const T&t);
|
|
void FindOrInsertHead(const T&t);
|
|
long FindAndDel(const T&t);
|
|
//二分查找,适用于升序表
|
|
long BFind(const T&t,long from = 0,long to = -1) const;
|
|
|
|
//operate
|
|
void SetAll(const T&t);
|
|
//稳定计数排序
|
|
void Arrange(bool bIncrease = true);
|
|
void Arrange(int (*cmp)(const T&,const T&));
|
|
//倒序
|
|
void Reverse(long from = 0,long to = -1);
|
|
|
|
protected:
|
|
long length;
|
|
T * pData;
|
|
};
|
|
|
|
template<class T>
|
|
SHArray<T>::~SHArray()
|
|
{
|
|
if (pData != NULL)
|
|
{
|
|
delete[] pData;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
bool SHArray<T>::IsValidIndex(long index) const
|
|
{
|
|
return index >=0 && index < length;
|
|
}
|
|
|
|
template<class T>
|
|
bool SHArray<T>::IsEmpty() const
|
|
{
|
|
return length == 0;
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::GetLength() const
|
|
{
|
|
return length;
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::GetLastIndex() const
|
|
{
|
|
return length - 1;
|
|
}
|
|
|
|
template<class T>
|
|
bool SHArray<T>::operator != (const SHArray<T>&array) const
|
|
{
|
|
return !((*this) == array);
|
|
}
|
|
|
|
template<class T>
|
|
T& SHArray<T>::operator[](long index)
|
|
{
|
|
return pData[index];
|
|
}
|
|
|
|
template<class T>
|
|
const T& SHArray<T>::GetAt(long index) const
|
|
{
|
|
return pData[index];
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::SetAt(long index,const T&t)
|
|
{
|
|
pData[index] = t;
|
|
}
|
|
|
|
template<class T>
|
|
T* SHArray<T>::GetBuffer() const
|
|
{
|
|
return pData;
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::InsertHead(const T&t)
|
|
{
|
|
Insert(0, t);
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::AddTail(const T& t)
|
|
{
|
|
Insert(length, t);
|
|
return GetLastIndex();
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::DelFirst()
|
|
{
|
|
Del(0);
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::DelTail()
|
|
{
|
|
Del(length - 1);
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::Clear()
|
|
{
|
|
if (pData != NULL)
|
|
{
|
|
delete[] pData;
|
|
pData = NULL;
|
|
length = 0;
|
|
}
|
|
}
|
|
|
|
|
|
template<class T>
|
|
long SHArray<T>::BFind(const T& t, long from, long to) const
|
|
{
|
|
if (to < 0 || to >= GetLength())
|
|
{
|
|
to = GetLastIndex();
|
|
}
|
|
|
|
if (from > to)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (t < GetAt(from))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (t > GetAt(to))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
while(from <= to)
|
|
{
|
|
long mid = (from + to) / 2;
|
|
const T& tCur = GetAt(mid);
|
|
if (t > tCur)
|
|
{
|
|
from = mid + 1;
|
|
}
|
|
else if (t < tCur)
|
|
{
|
|
to = mid - 1;
|
|
}
|
|
else
|
|
{
|
|
return mid;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
template<class T>
|
|
SHArray<T>::SHArray(long l)
|
|
{
|
|
if (l <= 0)
|
|
{
|
|
length = 0;
|
|
pData = NULL;
|
|
}
|
|
else
|
|
{
|
|
length = l;
|
|
pData = new T[l];
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
SHArray<T>::SHArray(const SHArray<T>& array) : pData(NULL), length(0)
|
|
{
|
|
Realloc(array.GetLength());
|
|
for (long i = 0;i < length; i++)
|
|
{
|
|
pData[i] = array.GetAt(i);
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
SHArray<T>& SHArray<T>::operator = (const SHArray<T>& array)
|
|
{
|
|
Realloc(array.GetLength());
|
|
for (long i = 0; i < length; i++)
|
|
{
|
|
pData[i] = array.GetAt(i);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class T>
|
|
SHArray<T>::SHArray(const SHTable<T>& table) : length(0), pData(NULL)
|
|
{
|
|
Realloc(table.GetLength());
|
|
long i = 0;
|
|
for (const T* pCur = table.GetFirst(); pCur != NULL; pCur = table.GetNext(pCur), i++)
|
|
{
|
|
pData[i] = *pCur;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::Realloc(long l,bool bCopy)
|
|
{
|
|
if (l != length)
|
|
{
|
|
if (l <= 0)
|
|
{
|
|
if (pData!=NULL)
|
|
{
|
|
delete[] pData;
|
|
}
|
|
length = 0;
|
|
pData = NULL;
|
|
}
|
|
else
|
|
{
|
|
T* pTemp = pData;
|
|
pData = new T[l];
|
|
if (bCopy)
|
|
{
|
|
if (l > length)
|
|
for (long i = 0;i < length; i++)
|
|
{
|
|
pData[i] = pTemp[i];
|
|
}
|
|
else
|
|
{
|
|
for (long i = 0; i < l; i++)
|
|
{
|
|
pData[i] = pTemp[i];
|
|
}
|
|
}
|
|
}
|
|
length = l;
|
|
if (pTemp != NULL)
|
|
{
|
|
delete[] pTemp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::SetAll(const T&t)
|
|
{
|
|
for (long i = 0; i < length; i++)
|
|
{
|
|
pData[i] = t;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
bool SHArray<T>::operator == (const SHArray<T>& array) const
|
|
{
|
|
if (length != array.GetLength())
|
|
{
|
|
return false;
|
|
}
|
|
for (long i = 0; i < length; i++)
|
|
{
|
|
if (pData[i] != array.GetAt(i))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::Insert(long index,const T& t)
|
|
{
|
|
T* pTemp = pData;
|
|
length++;
|
|
|
|
pData = new T[length];
|
|
for (long i = 0; i < length; i++)
|
|
{
|
|
if (i < index)
|
|
{
|
|
pData[i] = pTemp[i];
|
|
}
|
|
else if ( i > index)
|
|
{
|
|
pData[i] = pTemp[i - 1];
|
|
}
|
|
else
|
|
{
|
|
pData[i] = t;
|
|
}
|
|
}
|
|
if ( pTemp != NULL)
|
|
{
|
|
delete[] pTemp;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::Del(long index)
|
|
{
|
|
T* pTemp = pData;
|
|
length--;
|
|
|
|
if (length == 0)
|
|
{
|
|
pData = NULL;
|
|
}
|
|
else
|
|
{
|
|
pData = new T[length];
|
|
}
|
|
|
|
for (long i = 0; i < length; i++)
|
|
{
|
|
if (i < index)
|
|
{
|
|
pData[i] = pTemp[i];
|
|
}
|
|
else
|
|
{
|
|
pData[i] = pTemp[i + 1];
|
|
}
|
|
}
|
|
delete[] pTemp;
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::FindAndDel(const T&t)
|
|
{
|
|
long count = 0;
|
|
for (long i = 0;i < GetLength(); i++)
|
|
{
|
|
if (pData[i] == t)
|
|
{
|
|
Del(i);
|
|
i--;
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::Find(const T&t,long from,long to) const
|
|
{
|
|
if (to < 0 || to >= length)
|
|
{
|
|
to = length - 1;
|
|
}
|
|
|
|
for (long i = from; i <= to; i++)
|
|
{
|
|
if (pData[i] == t)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::Find(const T&t,SHQuene<long> &quene,long from,long to) const
|
|
{
|
|
if (to < 0 || to >= length)
|
|
{
|
|
to = length-1;
|
|
}
|
|
for (long i = from; i <= to; i++)
|
|
{
|
|
if (pData[i] == t)
|
|
{
|
|
quene.EnQuene(i);
|
|
}
|
|
}
|
|
return quene.GetLength();
|
|
}
|
|
|
|
//稳定计数排序
|
|
template<class T>
|
|
void SHArray<T>::Arrange(bool bIncrease)
|
|
{
|
|
if (GetLength() < 2)
|
|
{
|
|
return;
|
|
}
|
|
long *count = new long[GetLength()];
|
|
long i;
|
|
for (i = 0;i<GetLength();i++)
|
|
{
|
|
count[i] = i;
|
|
}
|
|
if (bIncrease)
|
|
{
|
|
for (i = 0;i < GetLastIndex(); i++)
|
|
{
|
|
for (long j = i + 1; j < GetLength(); j++)
|
|
if (pData[i] > pData[j])
|
|
{
|
|
count[i]++;
|
|
count[j]--;
|
|
}
|
|
}
|
|
for (i = 0;i < GetLength();i++)
|
|
{
|
|
if (count[i] != i)
|
|
{
|
|
long k,j;
|
|
T temp1 = pData[i],temp2;
|
|
k = count[i];
|
|
while(k != i)
|
|
{
|
|
temp2 = pData[k];//save
|
|
pData[k] = temp1;//transport data
|
|
temp1 = temp2;
|
|
j = k;
|
|
k = count[j];//save
|
|
count[j] = j;//count ok
|
|
}
|
|
pData[i] = temp1;
|
|
count[i] = i;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < GetLastIndex(); i++)
|
|
{
|
|
for (long j = i + 1; j < GetLength();j++)
|
|
{
|
|
if (pData[i] < pData[j])
|
|
{
|
|
count[i]++;
|
|
count[j]--;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0;i < GetLength();i++)
|
|
{
|
|
if (count[i] != i)
|
|
{
|
|
long k,j;
|
|
T temp1 = pData[i],temp2;
|
|
k = count[i];
|
|
while(k != i)
|
|
{
|
|
temp2 = pData[k];//save
|
|
pData[k] = temp1;//transport data
|
|
temp1 = temp2;
|
|
j = k;
|
|
k = count[j];//save
|
|
count[j] = j;//count ok
|
|
}
|
|
pData[i] = temp1;
|
|
count[i] = i;
|
|
}
|
|
}
|
|
}
|
|
delete[] count;
|
|
}
|
|
|
|
//稳定计数排序
|
|
template<class T>
|
|
void SHArray<T>::Arrange(int (*cmp)(const T&,const T&))
|
|
{
|
|
if (GetLength() < 2)
|
|
{
|
|
return;
|
|
}
|
|
|
|
long i;
|
|
long *count = new long[GetLength()];
|
|
for (i = 0; i < GetLength(); i++)
|
|
{
|
|
count[i] = i;
|
|
}
|
|
|
|
for (i = 0; i < GetLastIndex(); i++)
|
|
{
|
|
for (long j = i + 1; j < GetLength(); j++)
|
|
{
|
|
if (cmp(pData[i], pData[j]) > 0)
|
|
{
|
|
count[i]++;
|
|
count[j]--;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0;i < GetLength(); i++)
|
|
{
|
|
if (count[i] != i)
|
|
{
|
|
long k,j;
|
|
T temp1 = pData[i],temp2;
|
|
k = count[i];
|
|
while(k != i)
|
|
{
|
|
temp2 = pData[k];//save
|
|
pData[k] = temp1;//transport data
|
|
temp1 = temp2;
|
|
j = k;
|
|
k = count[j];//save
|
|
count[j] = j;//count ok
|
|
}
|
|
pData[i] = temp1;
|
|
count[i] = i;
|
|
}
|
|
}
|
|
|
|
delete[] count;
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::Reverse(long start,long end)
|
|
{
|
|
if (end == -1)
|
|
{
|
|
end = length - 1;
|
|
}
|
|
if (!IsValidIndex(start) || !IsValidIndex(end))
|
|
{
|
|
return;
|
|
}
|
|
|
|
long halfLength = (end - start + 1) / 2;
|
|
for (long i = 0; i < halfLength; i++)
|
|
{
|
|
T temp = pData[i + start];
|
|
long j = end - i;
|
|
pData[i + start] = pData[j];
|
|
pData[j] = temp;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
long SHArray<T>::FindOrAddTail(const T&t)
|
|
{
|
|
long pos = Find(t);
|
|
return pos != -1 ? pos : AddTail(t);
|
|
}
|
|
|
|
template<class T>
|
|
void SHArray<T>::FindOrInsertHead(const T&t)
|
|
{
|
|
long pos = Find(t);
|
|
if (pos == -1)
|
|
{
|
|
InsertHead(t);
|
|
}
|
|
}
|