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
|