//-------------------------------------------------------------------------------------------------------+ // 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 SqTable : public Table { public: SqTable(const Table&table); SqTable(const SqTable&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& operator = (const SqTable& table); SqTable& operator = (const Table& 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 SqTable::SqTable(const Table&table):pData(NULL),spaceSize(0) { this->DeepCopy(table); } template SqTable::SqTable(const SqTable&table):pData(NULL),spaceSize(0) { this->DeepCopy(table); } template SqTable& SqTable::operator = (const SqTable&table) { this->DeepCopy(table); return *this; } template SqTable& SqTable::operator = (const Table&table) { this->DeepCopy(table); return *this; } template void SqTable::SetCurData(const T &t) { pData[this->cur] = t; } template T& SqTable::GetCurData() { return pData[this->cur]; } template void SqTable::Clear() { this->length = 0; this->cur = -1; } template long SqTable::GetSpaceSize() const { return spaceSize; } template void SqTable::SetAllocUnit(long size) { allocUnit = size; } template long SqTable::GetAllocUnit() const { return allocUnit; } template const T* SqTable::GetFirst() const { return this->IsEmpty() ? NULL : pData; } template const T* SqTable::GetLast() const { return this->IsEmpty() ? NULL : pData + this->GetLastIndex(); } template const T* SqTable::GetNext(const T*p) const { return (p == NULL || p == (pData+this->GetLastIndex())) ? NULL : p + 1; } template const T* SqTable::GetPre(const T*p) const { return (p == NULL || p == pData) ? NULL : p - 1; } template const T& SqTable::GetAt(long index) const { return pData[index]; } template void SqTable::Attach(long size,T *p) { if (pData != NULL) { delete[] pData; } pData = p; spaceSize = this->length = size; } template T* SqTable::Detach() { T*p = pData; pData = NULL; spaceSize = this->length = 0; this->cur = -1; return p; } template void SqTable::Arrange(bool bIncrease) {//稳定计数排序 if (this->GetLength()<2) { return; } long *count = new long[this->GetLength()]; long i; for (i = 0;iGetLength();i++) { count[i] = i; } if (bIncrease) { for (i = 0;iGetLastIndex();i++) { for (long j = i+1;jGetLength();j++) { if (pData[i]>pData[j]) { count[i]++; count[j]--; } } } for (i = 0;iGetLength();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;iGetLastIndex();i++) { for (long j = i+1;jGetLength();j++) { if (pData[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 void SqTable::Arrange(int (*cmp)(const T&,const T&)) {//稳定计数排序 if (this->GetLength()<2) { return; } long *count = new long[this->GetLength()]; long i = 0; for (i = 0;iGetLength();i++) { count[i] = i; } for (i = 0;iGetLastIndex();i++) { for (long j = i+1;jGetLength();j++) { if (cmp(pData[i],pData[j])>0) { count[i]++; count[j]--; } } } for (i = 0;iGetLength();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 SqTable::SqTable(long size,long unit) { if (size <= 0) { pData = NULL; spaceSize = 0; } else { pData = new T[size]; spaceSize = size; } allocUnit = unit; } template SqTable::~SqTable() { if (pData != NULL) { delete[] pData; } } template void SqTable::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;ilength;i++) { pData[i] = pTemp[i]; } } else { for (long i = 0;ilength = spaceSize = newLength; } template bool SqTable::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 void SqTable::Realloc(long newLength) { if (newLength>spaceSize) { spaceSize = newLength+allocUnit; T*pTemp = pData; pData = new T[spaceSize]; if (pTemp != NULL) { for (long i = 0;ilength;i++) { pData[i] = pTemp[i]; } delete[] pTemp; } } this->length = newLength; } template void SqTable::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 void SqTable::DelCur() { for (long i = this->cur;iGetLastIndex();i++) { pData[i] = pData[i+1]; } this->Decrease(1); this->cur--; } #endif