Files
envi-code/SourceCode/Code2026/inc/AdsXRx/SqTable.h
T
2026-09-28 15:28:50 +08:00

459 lines
7.7 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : SqTable 模板类
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: SqTable 声明 高级动态数组,支持空间提前分配
// 注:空间的重分配将使未重分配前外部引用无效,使用类似table[i] = table[j]的语句时要特别注意!!!
// = Maintainers:
//
//-------------------------------------------------------------------------------------------------------+
#ifndef _SQTABLE_H_
#define _SQTABLE_H_
#ifndef _TABLE_H_
#include "Table.h"
#endif
template<class T> class SqTable : public Table<T>
{
public:
SqTable(const Table<T>&table);
SqTable(const SqTable<T>&table);
SqTable(long spaceSize = 0, long unit = 10);
virtual ~SqTable();
//only increase spaceSize,实现自动预先分配
virtual void Realloc(long newLength);
virtual void SetLength(long newLength,bool bCopy = true);
//const visit
virtual const T& GetAt(long index) const;
virtual const T* GetFirst() const;
virtual const T* GetLast() const;
virtual const T* GetPre(const T*p) const;
virtual const T* GetNext(const T*p) const;
//visit by this->cur
virtual T& GetCurData();
virtual void SetCurData(const T &t);
virtual void InsertCur(const T&t);
virtual void DelCur();
virtual void Clear();
//operate
virtual void Arrange(bool bIncrease = true);
virtual void Arrange(int (*cmp)(const T&,const T&));
SqTable<T>& operator = (const SqTable<T>& table);
SqTable<T>& operator = (const Table<T>& table);
//只改变己分配空间大小,成功执行返回true
bool SetSpaceSize(long size);
long GetSpaceSize() const;
//用于自动预先分配
void SetAllocUnit(long size);
long GetAllocUnit() const;
//基于外部空间重新构造,将释放原空间,size为外部空间可容纳的数据量
void Attach(long size,T *p);
//释放空间的控制权,恢复初始状态
T* Detach();
protected:
T* pData; //如果spaceSize = 0,pData 为 NULL
long spaceSize; //总是 >= 0;
long allocUnit; //总是 >= 0;
};
template<class T>
SqTable<T>::SqTable(const Table<T>&table):pData(NULL),spaceSize(0)
{
this->DeepCopy(table);
}
template<class T>
SqTable<T>::SqTable(const SqTable<T>&table):pData(NULL),spaceSize(0)
{
this->DeepCopy(table);
}
template<class T>
SqTable<T>& SqTable<T>::operator = (const SqTable<T>&table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
SqTable<T>& SqTable<T>::operator = (const Table<T>&table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
void SqTable<T>::SetCurData(const T &t)
{
pData[this->cur] = t;
}
template<class T>
T& SqTable<T>::GetCurData()
{
return pData[this->cur];
}
template<class T>
void SqTable<T>::Clear()
{
this->length = 0;
this->cur = -1;
}
template<class T>
long SqTable<T>::GetSpaceSize() const
{
return spaceSize;
}
template<class T>
void SqTable<T>::SetAllocUnit(long size)
{
allocUnit = size;
}
template<class T>
long SqTable<T>::GetAllocUnit() const
{
return allocUnit;
}
template<class T>
const T* SqTable<T>::GetFirst() const
{
return this->IsEmpty() ? NULL : pData;
}
template<class T>
const T* SqTable<T>::GetLast() const
{
return this->IsEmpty() ? NULL : pData + this->GetLastIndex();
}
template<class T>
const T* SqTable<T>::GetNext(const T*p) const
{
return (p == NULL || p == (pData+this->GetLastIndex())) ? NULL : p + 1;
}
template<class T>
const T* SqTable<T>::GetPre(const T*p) const
{
return (p == NULL || p == pData) ? NULL : p - 1;
}
template<class T>
const T& SqTable<T>::GetAt(long index) const
{
return pData[index];
}
template<class T>
void SqTable<T>::Attach(long size,T *p)
{
if (pData != NULL)
{
delete[] pData;
}
pData = p;
spaceSize = this->length = size;
}
template<class T>
T* SqTable<T>::Detach()
{
T*p = pData;
pData = NULL;
spaceSize = this->length = 0;
this->cur = -1;
return p;
}
template<class T>
void SqTable<T>::Arrange(bool bIncrease)
{//稳定计数排序
if (this->GetLength()<2)
{
return;
}
long *count = new long[this->GetLength()];
long i;
for (i = 0;i<this->GetLength();i++)
{
count[i] = i;
}
if (bIncrease)
{
for (i = 0;i<this->GetLastIndex();i++)
{
for (long j = i+1;j<this->GetLength();j++)
{
if (pData[i]>pData[j])
{
count[i]++;
count[j]--;
}
}
}
for (i = 0;i<this->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<this->GetLastIndex();i++)
{
for (long j = i+1;j<this->GetLength();j++)
{
if (pData[i]<pData[j])
{
count[i]++;
count[j]--;
}
}
}
for (i = 0;i<this->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 SqTable<T>::Arrange(int (*cmp)(const T&,const T&))
{//稳定计数排序
if (this->GetLength()<2)
{
return;
}
long *count = new long[this->GetLength()];
long i = 0;
for (i = 0;i<this->GetLength();i++)
{
count[i] = i;
}
for (i = 0;i<this->GetLastIndex();i++)
{
for (long j = i+1;j<this->GetLength();j++)
{
if (cmp(pData[i],pData[j])>0)
{
count[i]++;
count[j]--;
}
}
}
for (i = 0;i<this->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>
SqTable<T>::SqTable(long size,long unit)
{
if (size <= 0)
{
pData = NULL;
spaceSize = 0;
}
else
{
pData = new T[size];
spaceSize = size;
}
allocUnit = unit;
}
template<class T>
SqTable<T>::~SqTable()
{
if (pData != NULL)
{
delete[] pData;
}
}
template<class T>
void SqTable<T>::SetLength(long newLength,bool bCopy)
{
if (newLength != spaceSize)
{
T*pTemp = pData;
if (newLength>0)
{
pData = new T[newLength];
}
else
{
pData = NULL;
}
if (pTemp != NULL)
{
if (bCopy)
{
if (newLength>this->length)
{
for (long i = 0;i<this->length;i++)
{
pData[i] = pTemp[i];
}
}
else
{
for (long i = 0;i<newLength;i++)
{
pData[i] = pTemp[i];
}
}
}
delete[] pTemp;
}
}
this->length = spaceSize = newLength;
}
template<class T>
bool SqTable<T>::SetSpaceSize(long size)
{
if (size >= this->GetLength())
{
if (size != spaceSize)
{
long oldLength = this->GetLength();
SetLength(size,true);
this->length = oldLength;
}
return true;
}
return false;
}
template<class T>
void SqTable<T>::Realloc(long newLength)
{
if (newLength>spaceSize)
{
spaceSize = newLength+allocUnit;
T*pTemp = pData;
pData = new T[spaceSize];
if (pTemp != NULL)
{
for (long i = 0;i<this->length;i++)
{
pData[i] = pTemp[i];
}
delete[] pTemp;
}
}
this->length = newLength;
}
template<class T>
void SqTable<T>::InsertCur(const T&t)
{
this->Increase(1);
for (long i = this->GetLastIndex();i>this->cur;i--)
{
pData[i] = pData[i-1];
}
pData[this->cur] = (T&)t;
}
template<class T>
void SqTable<T>::DelCur()
{
for (long i = this->cur;i<this->GetLastIndex();i++)
{
pData[i] = pData[i+1];
}
this->Decrease(1);
this->cur--;
}
#endif