259 lines
4.3 KiB
C++
259 lines
4.3 KiB
C++
//-----------------------------------------------------------------------------+
|
||
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
||
// = FileName : TPGeGList.h
|
||
// = Version : ver2.0
|
||
// = Author : xlc
|
||
// = CreateDate : 2002-09-09
|
||
// = Description: 类的声明
|
||
// = Maintainers: cpp中176行的temp变量没有声明,如何编译?
|
||
//
|
||
//-----------------------------------------------------------------------------+
|
||
#ifndef _TPGEGLIST_H_
|
||
#define _TPGEGLIST_H_
|
||
|
||
//递归链或图链,方便链动态组建和链高级操作
|
||
//每个链结点都代表和管理由本结点和后续链组成的链。
|
||
template<class T> class TPGeGList
|
||
{
|
||
public:
|
||
|
||
//构造
|
||
TPGeGList();
|
||
|
||
//析构,有后续子环路时不能调用下列函数!!!
|
||
virtual ~TPGeGList();
|
||
|
||
virtual void DCNNext();
|
||
|
||
virtual void CNNext(TPGeGList* pList);
|
||
|
||
//数据
|
||
const T& GetData()const;
|
||
|
||
const T& GetData(long i)const;
|
||
|
||
T& Data();
|
||
|
||
T& Data(long i);
|
||
|
||
//释放所有后续结点,本结点成为终止结点
|
||
void ReleaseAll();
|
||
|
||
//链接
|
||
void SetNext(TPGeGList<T>* pList);
|
||
//插入合并
|
||
void InsertNext(TPGeGList<T>* pList);
|
||
|
||
//摘取长度为num的后续子链,,num must be >0 and valid!!!
|
||
TPGeGList<T>* FetchNext(long num = 1);
|
||
|
||
//删除长度为num的后续子链
|
||
void DelNext(long num = 1);
|
||
|
||
//遍历,有后续子环路时不能调用下列函数!!
|
||
long Length()const;
|
||
|
||
TPGeGList<T>* Next()const;
|
||
|
||
TPGeGList<T>* GetAt(long i)const;
|
||
|
||
TPGeGList<T>* GetTail()const;
|
||
|
||
bool IsClosed()const;
|
||
|
||
//返回新链首,如果本结点非链首,将在本结点处形成分叉!如果是环路将保持环路
|
||
TPGeGList<T>* Reverse();
|
||
|
||
const TPGeGList* Find(T&t)const;
|
||
|
||
protected:
|
||
|
||
T data;
|
||
|
||
TPGeGList *next;
|
||
};
|
||
|
||
template<class T>
|
||
TPGeGList<T>::TPGeGList()
|
||
: next(NULL)
|
||
{
|
||
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>::~TPGeGList()
|
||
{
|
||
//析构时需保证前链接已经断开!!
|
||
ReleaseAll();
|
||
}
|
||
|
||
template<class T>
|
||
const T& TPGeGList<T>::GetData() const
|
||
{
|
||
return data;
|
||
}
|
||
|
||
template<class T>
|
||
T& TPGeGList<T>::Data()
|
||
{
|
||
return data;
|
||
}
|
||
|
||
template<class T>
|
||
const T& TPGeGList<T>::GetData(long i) const
|
||
{
|
||
return GetAt(i)->GetData();
|
||
}
|
||
|
||
template<class T>
|
||
T& TPGeGList<T>::Data(long i)
|
||
{
|
||
return GetAt(i)->Data();
|
||
}
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::SetNext(TPGeGList<T>*pList)
|
||
{
|
||
next = pList;
|
||
}
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::CNNext(TPGeGList*pList)
|
||
{
|
||
next = pList;
|
||
}
|
||
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::DCNNext()
|
||
{
|
||
next = NULL;
|
||
}
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::DelNext(long num/* = 1*/)
|
||
{
|
||
delete FetchNext(num);
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>* TPGeGList<T>::Next() const
|
||
{
|
||
return next;
|
||
}
|
||
|
||
template<class T>
|
||
bool TPGeGList<T>::IsClosed() const
|
||
{
|
||
return GetTail()->Next() == this;
|
||
}
|
||
|
||
|
||
template<class T>
|
||
const TPGeGList<T>* TPGeGList<T>::Find(T&t) const
|
||
{
|
||
if (data == t)
|
||
{
|
||
return this;
|
||
}
|
||
|
||
for (const TPGeGList* p = Next();p != NULL && p != this;p = p->Next())
|
||
{
|
||
if (p->GetData() == t)
|
||
{
|
||
return p;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>* TPGeGList<T>::Reverse()
|
||
{
|
||
TPGeGList<T> *pPre = this,*pCur = Next();
|
||
while(pCur != NULL && pCur != this)
|
||
{
|
||
TPGeGList<T>* temp = pCur->Next();
|
||
pCur->SetNext(pPre);
|
||
pPre = pCur;
|
||
pCur = temp;
|
||
}
|
||
if (pCur == NULL)
|
||
{
|
||
SetNext(NULL);
|
||
return pPre;
|
||
}
|
||
else
|
||
{
|
||
SetNext(pPre);
|
||
return this;
|
||
}
|
||
}
|
||
|
||
template<class T>
|
||
long TPGeGList<T>::Length() const
|
||
{
|
||
long count = 1;
|
||
for (TPGeGList*pCur = Next();pCur != NULL && pCur != this;pCur = pCur->Next())
|
||
{
|
||
count++;
|
||
}
|
||
return count;
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>* TPGeGList<T>::GetAt(long i) const
|
||
{
|
||
const TPGeGList<T>*pCur = this;
|
||
for (long j = 0;j<i && pCur != NULL;j++,pCur = pCur->Next());
|
||
return (TPGeGList<T>*)pCur;
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>* TPGeGList<T>::GetTail() const
|
||
{
|
||
const TPGeGList<T>*pCur;
|
||
for (pCur = this;pCur->Next() != this && pCur->Next() != NULL;pCur = pCur->Next());
|
||
return (TPGeGList<T>*)pCur;
|
||
}
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::InsertNext(TPGeGList<T>*pList)
|
||
{
|
||
TPGeGList<T>*pOldNext = Next();
|
||
CNNext(pList);
|
||
if (pOldNext != NULL)
|
||
{
|
||
pList->GetTail()->CNNext(pOldNext);
|
||
}
|
||
}
|
||
|
||
template<class T>
|
||
TPGeGList<T>* TPGeGList<T>::FetchNext(long num)
|
||
{
|
||
TPGeGList<T>*pOldNext = Next();
|
||
TPGeGList<T>*pLast = GetAt(num);
|
||
TPGeGList<T>*pTemp = pLast->Next();
|
||
if (pTemp != NULL)
|
||
{
|
||
pLast->DCNNext();
|
||
CNNext(pTemp);
|
||
}
|
||
return pOldNext;
|
||
}
|
||
|
||
template<class T>
|
||
void TPGeGList<T>::ReleaseAll()
|
||
{
|
||
for (TPGeGList<T> *pCur = Next();pCur != NULL && pCur != this;)
|
||
{
|
||
TPGeGList<T>*temp = pCur->Next();
|
||
pCur->SetNext(NULL);
|
||
delete pCur;
|
||
pCur = temp;
|
||
}
|
||
SetNext(NULL);
|
||
}
|
||
|
||
#endif |