//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TSqPTable 模板类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TSqPTable 声明 // 动态指针数组,内部可以自动分配、释放内存,同时提供外部内存分配、释放接口。 // 同名函数功能、使用方法、要求与SqTable完全相同。 // 未访问的数据不分配内存,数据一经访问,自动分配内存,支持空数据。 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #ifndef _TSQPTABLE_H_ #define _TSQPTABLE_H_ #ifndef _TSQTABLE_H_ #include "TSqTable.h" #endif templateclass TSqPTable { public: TSqPTable(long size = 0,long unit = 10); TSqPTable(const TSqPTable&ptable); TSqPTable(const TTable&table); virtual ~TSqPTable(); TSqPTable& operator = (const TSqPTable&ptable); TSqPTable& operator = (const TTable&table); bool operator == (const TSqPTable&pTable) const; bool operator != (const TSqPTable&pTable) const; void Increase(long num); void Decrease(long num); //always copy old data void SetLength(long newLength,bool bCopy = true); //attribute bool IsValidIndex(long index) const; bool IsEmpty() const; long GetLength() const; long GetLastIndex() const; void SetAllocUnit(long size); long GetAllocUnit() const; long GetDataNum() const; bool IsEmptyData(long index) const; bool IsCurEmpty() const; //sequence visit interface bool IsOut() const; bool IsBegin() const; bool IsEnd() const; long GetCur() const; void MoveTo(long index); void MoveToFirst(); void MoveToLast(); void MoveToNext(); void MoveToPre(); T& GetCurData(); void SetCurData(const T&t); //ramdon visit interface,index must be valid!!! const T& GetAt(long index) const; T& operator[](long index); //pointer interface T* operator()(long index); //不能对它返加的指针本身进行delete操作!!! void SetCurData(T*p); //将外部分配的数据填入指针表,p 可以是NULL指针;自动调整指针表长度; //外部一般应在堆中分配内存,以使TSqPTable正确对其进行管理; //否则应使用SetOutData(index,NULL)及时将其清理。 //if index<0,ignore. void SetOutData(long index,T*p); void Insert(long index,T*p); void InsertCur(T*p); void InsertHead(T*p); long AddTail(T*p); //在第一个空数据处添加,无空数据项则末尾添加,返回索引。 long FillIn(T*p); //仅释放数据空间,不删除指针空间,不改变数组长度,不移动cur. void ReleaseCur(); void Release(long i); void ReleaseAll(); void InsertCur(const T&t); void DelCur(); void Insert(long index,const T&t); void InsertHead(const T&t); long AddTail(const T&t); //在第一个空数据处添加,无空数据项则末尾添加,返回索引。 long FillIn(const T&t); void Del(long index); void DelFirst(); void DelTail(); //取走数据,清空指针,但不删除指针表项! T* FetchCur(); T* Fetch(long i); T* FetchFirst(); T* FetchLast(); void Clear(); void ExChange(long i,long j); //索引以未移动时为准 bool Move(long from,long to); long FindOrAddTail(const T& t); void FindOrInsertHead(const T& t); long FindAndDel(const T& t); long Find(const T& t,long from = 0,long to = -1) const; long Find(const T& t,TQuene& quene,long from = 0,long to = -1) const; void SetAll(const T&t); //稳定计数排序, 不支持空数据!但速度快。 void Arrange(bool bIncrease = true); //稳定计数排序 void Arrange(int (*cmp)(const T&,const T&)); //稳定计数排序,空数据将排列在最后 void ArrangeEx(bool bIncrease = true); void Reverse(long start = 0,long end = -1); protected: TSqTable table; }; template TSqPTable::TSqPTable(long size,long unit):table(size,unit) { } template TSqPTable::TSqPTable(const TSqPTable&ptable) { *this = ptable; } template TSqPTable::TSqPTable(const TTable&table) { *this = table; } template bool TSqPTable::IsValidIndex(long index) const { return table.IsValidIndex(index); } template bool TSqPTable::IsEmpty() const { return table.IsEmpty(); } template long TSqPTable::GetLength() const { return table.GetLength(); } template long TSqPTable::GetLastIndex() const { return table.GetLastIndex(); } template void TSqPTable::SetAllocUnit(long size) { table.SetAllocUnit(size); } template long TSqPTable::GetAllocUnit() const { return table.GetAllocUnit(); } template bool TSqPTable::IsCurEmpty() const { return IsEmptyData(GetCur()); } template bool TSqPTable::operator != (const TSqPTable&pTable) const { return !(*this == pTable); } template bool TSqPTable::IsOut() const { return table.IsOut(); } template bool TSqPTable::IsBegin() const { return table.IsBegin(); } template bool TSqPTable::IsEnd() const { return table.IsEnd(); } template long TSqPTable::GetCur() const { return table.GetCur(); } template void TSqPTable::MoveTo(long index) { table.MoveTo(index); } template void TSqPTable::MoveToFirst() { table.MoveToFirst(); } template void TSqPTable::MoveToLast() { table.MoveToLast(); } template void TSqPTable::MoveToNext() { table.MoveToNext(); } template void TSqPTable::MoveToPre() { table.MoveToPre(); } template void TSqPTable::SetCurData(T*p) { if (!IsOut()) { SetOutData(GetCur(),p); } } template void TSqPTable::Insert(long index,T*p) { MoveTo(index); InsertCur(p); } template void TSqPTable::InsertCur(T*p) { table.InsertCur(p); } template void TSqPTable::InsertHead(T*p) { Insert(0,p); } template long TSqPTable::AddTail(T*p) { Insert(GetLength(),p); return GetLastIndex(); } template void TSqPTable::Release(long i) { MoveTo(i); ReleaseCur(); } template void TSqPTable::Insert(long index,const T&t) { MoveTo(index); InsertCur(t); } template void TSqPTable::InsertHead(const T&t) { MoveToFirst(); InsertCur(t); } template long TSqPTable::AddTail(const T&t) { MoveTo(GetLength()); InsertCur(t); return GetLastIndex(); } template void TSqPTable::Del(long index) { MoveTo(index); DelCur(); } template void TSqPTable::DelFirst() { MoveToFirst(); DelCur(); } template void TSqPTable::DelTail() { MoveToLast(); DelCur(); } template void TSqPTable::ExChange(long i,long j) { table.Exchange(i,j); } template bool TSqPTable::Move(long from,long to) { return table.Move(from,to); } template long TSqPTable::FindOrAddTail(const T&t) { long pos = Find(t,0,GetLastIndex()); return pos != NOT_FOUND ? pos : AddTail(t); } template void TSqPTable::FindOrInsertHead(const T&t) { long pos = Find(t,0,GetLastIndex()); if (pos == NOT_FOUND) { InsertHead(t); } } template void TSqPTable::Reverse(long start,long end) { table.Reverse(start,end); } template T* TSqPTable::Fetch(long i) { MoveTo(i); return FetchCur(); } template T* TSqPTable::FetchFirst() { MoveToFirst(); return FetchCur(); } template T* TSqPTable::FetchLast() { MoveToLast(); return FetchCur(); } template const T& TSqPTable::GetAt(long index) const { return *(table.GetAt(index)); } template T* TSqPTable::FetchCur() { if (IsOut()) { return NULL; } T*p = table.GetCurData(); table.SetCurData(NULL); return p; } template bool TSqPTable::IsEmptyData(long index) const { return IsValidIndex(index)?table.GetAt(index) == NULL:true; } template T& TSqPTable::GetCurData() { if (IsCurEmpty()) { T *p = new T; table.SetCurData(p); } return *(table.GetCurData()); } template void TSqPTable::SetCurData(const T&t) { if (IsCurEmpty()) { T *p = new T; table.SetCurData(p); } *(table.GetCurData()) = t; } template T& TSqPTable::operator[](long index) {//index must be >= 0!!! if (index >= GetLength()) { Increase(index+1-GetLength()); } MoveTo(index); return GetCurData(); } template T* TSqPTable::operator()(long index) { if (index >= GetLength()) { Increase(index+1-GetLength()); } MoveTo(index); return table.GetCurData(); } template long TSqPTable::FillIn(const T&t) { long i(0); for (i = 0;!IsEmptyData(i);i++); (*this)[i] = t; return i; } template long TSqPTable::FillIn(T*p) { long i(0); for (i = 0;!IsEmptyData(i);i++); SetOutData(i,p); return i; } template long TSqPTable::GetDataNum() const { long count = 0; for (long i = 0;i void TSqPTable::SetOutData(long index,T*p) { if (index<0) { return; } if (IsEmptyData(index)) { if (index >= GetLength()) { Increase(index+1-GetLength()); } table[index] = p; } else { delete table[index]; table[index] = p; } } template void TSqPTable::ReleaseCur() {//仅释放数据空间,不删除指针空间,不改变数组长度,不移动cur. if (IsCurEmpty()) { return; } delete table.GetCurData(); table.SetCurData(NULL); } template void TSqPTable::InsertCur(const T&t) { T*p = new T; *p = t; table.InsertCur(p); } template void TSqPTable::DelCur() { if (table.GetCurData() == NULL) { delete table.GetCurData(); } table.DelCur(); } template void TSqPTable::ReleaseAll() { for (MoveToFirst();!IsOut();MoveToNext()) { ReleaseCur(); } } template void TSqPTable::Clear() { ReleaseAll(); table.Clear(); } template long TSqPTable::FindAndDel(const T&t) { int count(0); for (long i = 0;i long TSqPTable::Find(const T&t,long from,long to) const { if (to == -1 || to >= GetLength()) { to = GetLastIndex(); } for (long i = from;i <= to;i++) { if (!IsEmptyData(i) && GetAt(i) == t) { return i; } } return NOT_FOUND; } template long TSqPTable::Find(const T&t,TQuene&quene,long from,long to) const { if (to == -1 || to >= GetLength()) { to = GetLastIndex(); } for (long i = from;i <= to;i++) { if (!IsEmptyData(i) && GetAt(i) == t) { return quene.EnQuene(i); } } return quene.GetLength(); } template void TSqPTable::SetAll(const T&t) { for (MoveToFirst();!IsOut();MoveToNext()) { SetCurData(t); } } template TSqPTable& TSqPTable::operator = (const TSqPTable&ptable) { SetLength(ptable.GetLength()); for (long i = 0;i bool TSqPTable::operator == (const TSqPTable&pTable) const { if (pTable.GetLength() != GetLength()) { return false; } for (long i = 0;i TSqPTable& TSqPTable::operator = (const TTable&t) { SetLength(t.GetLength(),false); const T*pCur = NULL; for (MoveToFirst(),pCur = t.GetFirst();!IsOut();MoveToNext(),pCur = t.GetNext(pCur)) { SetCurData(*pCur); } return *this; } template TSqPTable::~TSqPTable() { ReleaseAll(); } template void TSqPTable::Increase(long num) { long oldLength = GetLength(); long oldCur = GetCur(); table.Increase(num); for (long i = oldLength;i void TSqPTable::Decrease(long num) { long oldLength = GetLength(); long oldCur = GetCur(); for (long i = oldLength-num;i void TSqPTable::SetLength(long newLength,bool bCopy) { long oldCur = GetCur(); long oldLength = GetLength(); for (MoveTo(newLength);!IsOut();MoveToNext()) { if (!IsCurEmpty()) { delete table.GetCurData(); } } table.SetLength(newLength); for (MoveTo(oldLength);!IsOut();MoveToNext()) { table.SetCurData(NULL); } MoveTo(oldCur); } template void TSqPTable::Arrange(bool bIncrease) { if (GetLength()<2) { return; } long *count = new long[GetLength()]; long i; for (i = 0;i*(table[j])) { count[i]++; count[j]--; } } } for (i = 0;i void TSqPTable::Arrange(int (*cmp)(const T&,const T&)) { if (GetLength()<2) { return; } long *count = new long[GetLength()]; long i; for (i = 0;i0) { count[i]++; count[j]--; } } } for (i = 0;i void TSqPTable::ArrangeEx(bool bIncrease) { if (GetLength()<2) return; long *count = new long[GetLength()]; long i; for (i = 0;i*(table[j]))) { count[i]++; count[j]--; } } } for (i = 0;i