Files
envi-code/SourceCode/Code2026/Dimension/SHArray.h
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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);
}
}