459 lines
7.7 KiB
C++
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
|
|
|