dzqlist.cpp
来自「一种基于二维链表的稀疏矩阵模半板类设计 A template Class of」· C++ 代码 · 共 951 行 · 第 1/2 页
CPP
951 行
return len;
}
template<class T>
bool Chain<T>::Find(int k, T& x) const
{ // 寻找链表中的第k个元素,并将其传送至x
//如果不存在第k个元素,则返回f a l s e,否则返回t r u e
if (k<1)
return false;
ChainNode<T> *current = first;
int index = 1; // current的索引
while (index < k && current!=NULL)
{
current = current->link;
index++;
}
if (current!=NULL)
{
x = current->data;
return true;
}
return false; // 不存在第k个元素
}
template<class T>
int Chain<T>::Search(const T& x) const
{ // 寻找x,如果发现x,则返回x的地址
//如果x不在链表中,则返回0
ChainNode<T> *current = first;
int index = 1; // current的索引
while (current!=NULL && current->data != x)
{
current = current->link;
index++;
}
if (current!=NULL) return index;
return 0;
}
template<class T>
void Chain<T>::Output(ostream& out) const
{ // 将链表元素送至输出流
ChainNode<T> *current;
for (current = first; current!=NULL; current = current->link)
out << current->data << " ";
}
template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out);
return out;
}
template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{ // 把第k个元素取至x,然后从链表中删除第k个元素
//如果不存在第k个元素,则引发异常OutOfBounds
if (k < 1 || NULL==first)
throw OutOfBounds(); // 不存在第k个元素
// p最终将指向第k个节点
ChainNode<T> *p = first;
// 将p移动至第k个元素,并从链表中删除该元素
if (k == 1) // p已经指向第k个元素
{
if(first==last) // and only one Node.
{
first = first->link; // 删除之
last=first;
}
else
{
first = first->link; // 删除之
}
}
else
{ // 用q指向第k - 1个元素
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q!=NULL; index++)
q= q->link;
if (NULL==q || (q->link)==NULL)
throw OutOfBounds(); //不存在第k个元素
p = q->link; // 存在第k个元素
if(p==last)
last=q;
q->link = p->link;
} // 从链表中删除该元素
//保存第k个元素并释放节点p
x= p->data;
delete p;
return *this;
}
template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{ // 在第k个元素之后插入x
//如果不存在第k个元素,则引发异常O u t O f B o u n d s
// 如果没有足够的空间,则传递N o M e m异常
if (k < 0) throw OutOfBounds();
// p最终将指向第k个节点
ChainNode<T> *p = first;
//将p移动至第k个元素
for (int index = 1; index < k && p!=NULL; index++)
p = p->link;
if (k > 0 && p==NULL) throw OutOfBounds(); //不存在第k个元素
// 插入
ChainNode<T> *y=new ChainNode<T>;
y->data = x;
if (k!=0)
{// 在p之后插入
y->link = p->link;
p->link = y;
}
else
{// 作为第一个元素插入
y->link = first;
first = y;
if(NULL==last) //original list null.
{
last=first;
}
}
if(y->link==NULL) last=y;
return *this;
}
template<class T>
void Chain<T>::Erase()
{ //删除链表中的所有节点
ChainNode<T> *next;
while (first!=NULL)
{
next = first->link;
delete first;
first = next;
}
last=NULL;
}
template <class T>
Chain<T>& Chain<T>::Append(const T& x)
{
ChainNode<T> *temp=new ChainNode<T>;
temp->data=x;
temp->link=NULL;
if(first!=NULL )
{
last->link=temp;
last=temp;
}
else
{
first=temp;
last=first;
}
return *this;
}
template<class T>
Chain<T>& Chain<T>::AppendLeft(const T& x)
{
ChainNode<T> *pTemp=new ChainNode<T>;
pTemp->data=x;
pTemp->link=first;
first=pTemp;
if(last==NULL)
{
last=pTemp;
}
return *this;
}
template<class T>
Chain<T>& Chain<T>::Reverse()
{
ChainNode<T> *pScan;
ChainNode<T> *pTemp;
ChainNode<T> *pTracer;
if(first==last) //only one node or empty
return *this;
pTracer=first;
pScan=first->link;
while(pScan!=NULL)
{
pTemp=pScan;
pScan=pScan->link;
pTemp->link=pTracer;
pTracer=pTemp;
}
pTemp=first;
first=last;
last=pTemp;
last->link=NULL;
return *this;
}
template<class T>
Chain<T>& Chain<T>::Reverse(Chain<T>& dest,Chain<T>& src)
{
//Without delete any memory in src.(just change pointers' content).
//and without allocate any memory.
dest.Erase();
ChainNode<T> *pTemp;
if(NULL==src.first) //src empty.
return dest;
dest.first=src.first;
dest.last=src.first; //no error!!!
src.first=src.first->link;
while(src.first!=NULL)
{
pTemp=src.first;
src.first=src.first->link;
pTemp->link=dest.first;
dest.first=pTemp;
}
src.first=src.last=NULL;
dest.last->link=NULL;
return dest;
}
template<class T>
Chain<T>& Chain<T>::Emerge(Chain<T>& dest,Chain<T>& srcA,Chain<T>& srcB)
{
//Chain A and B are sorted.Merge A and B to dest.
//Chain A and B are empty after merged.
//the dest is sorted via ascending.
ChainNode<T>* pScanA=srcA.first;
ChainNode<T>* pScanB=srcB.first;
ChainNode<T>* pScanDest=NULL;
dest.Erase();
if(pScanA==NULL && pScanB==NULL) //both A and B are NULL.
{
return dest;
}
if(pScanA==NULL) //only A null.
{
dest.first=srcB.first;
dest.last=srcB.last;
srcB.first=srcB.last=NULL;
return dest;
}
if(pScanB==NULL) //only B null.
{
dest.first=srcA.first;
dest.last=srcA.last;
srcA.first=srcA.last=NULL;
return dest;
}
if( (srcA.first->data) > (srcA.last->data) ) //make sure srcA ascending sort.
{
srcA.Reverse(srcA);
pScanA=srcA.first; //must reassignment.
}
if( (srcB.first->data) > (srcB.last->data) ) //make sure srcB ascending sort.
{
srcB.Reverse(srcB);
pScanB=srcB.first; //must reassignment.
}
if( (srcA.last)->data <= (srcB.first)->data ) //direct link(A->B)
{
dest.first=srcA.first;
(srcA.last)->link=srcB.first;
dest.last=srcB.last;
srcA.first=srcA.last=NULL;
srcB.first=srcB.last=NULL;
return dest;
}
if( (srcB.last)->data <= (srcA.first)->data ) //direct link(B->A)
{
dest.first=srcB.first;
(srcB.last)->link=srcA.first;
dest.last=srcA.last;
srcA.first=srcA.last=NULL;
srcB.first=srcB.last=NULL;
return dest;
}
//Initial dest.
if(pScanA->data <=pScanB->data)
{
pScanDest=pScanA;
pScanA=pScanA->link;
}
else
{
pScanDest=pScanB;
pScanB=pScanA->link;
}
dest.first=pScanDest;
while(pScanA!=NULL && pScanB!=NULL) //normal state.
{
if(pScanA->data <= pScanB->data)
{
pScanDest->link=pScanA;
pScanDest=pScanA;
pScanA=pScanA->link;
}
else
{
pScanDest->link=pScanB;
pScanDest=pScanB;
pScanB=pScanB->link;
}
}
if(pScanA==NULL)
{
pScanDest->link=pScanB;
dest.last=srcB.last;
}
else
{
pScanDest->link=pScanA;
dest.last=srcA.last;
}
srcA.first=srcA.last=NULL;
srcB.first=srcB.last=NULL;
return dest;
}
template<class T>
void Chain<T>::Split(Chain<T>& destA, Chain<T>& destB, Chain<T>& srcC)
{
ChainNode<T> *pA=NULL;
ChainNode<T> *pB=NULL;
ChainNode<T> *pScan=NULL;
destA.Erase();
destB.Erase();
if(srcC.first==NULL) //srcC empty.
return;
if(srcC.first==srcC.last) //srcC only one node.
{
destA.first=srcC.first;
destA.last=srcC.first;
srcC.first=srcC.last=NULL;
return;
}
//equal or more than two nodes.
pA=srcC.first; //Initial.
destA.first=pA;
pB=(srcC.first)->link;
destB.first=pB;
pScan=pB->link;
bool LinkToA=true;
while(pScan!=NULL)
{
if(LinkToA) //select to A
{
pA->link=pScan;
pA=pScan;
pScan=pScan->link;
}
else
{ //select to B
pB->link=pScan;
pB=pScan;
pScan=pScan->link;
}
LinkToA=!LinkToA;
}
pA->link=NULL;
pB->link=NULL;
destA.last=pA;
destB.last=pB;
srcC.first=srcC.last=NULL;
}
//Chain over...........................................................................
//Chain iterator.......................................................................
template<class T>
class ChainIterator
{
public:
T* Initialize(const Chain<T>& c)
{
pLocation = c.first;
if (pLocation!=NULL)
return pLocation->data;
return 0;
}
T* Next()
{
if (pLocation==NULL)
return 0;
pLocation = pLocation->link;
if (pLocation!=NULL)
return pLocation->data;
return 0;
}
private:
ChainNode<T> *plocation;
};
//Chain iterator over.......................................................................
void OutOfBounds()
{
cout<<"OutOfBounds!"<<endl;
exit(0);
}
template <class T>
ostream& operator<<(ostream& out,const SigLinkedCirList<T>& c)
{
c.Output(out);
return out;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?