⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlink.h

📁 可能是能找到的处理速度最快
💻 H
字号:
#ifndef TLINK_H_
#define TLINK_H_

#include<assert.h>
#include<stdio.h>
template<class T> class CLink;

template<class T> class CLinkNode
{
	T *data;
	CLinkNode<T> *next;
	int Own;
public:
	T &Data()	{	return *data;	}
	CLinkNode(int O,T *InitData=NULL,CLinkNode<T> *p=NULL):
	data(InitData),		next(p),	Own(O)	{	}

	CLinkNode(T &InitData,CLinkNode<T> *p=NULL):
					next(p),Own(1)
	{	data=new T(InitData);	}
	~CLinkNode()
	{
		if (Own&&data)
			delete data;
	}
	friend class CLink<T>;
};

template<class T> class CLink
{
	CLinkNode<T> *head;
	CLinkNode<T> *tail;
	CLinkNode<T> *CurrentNode;
	CLinkNode<T> *LoopMark;
	unsigned long count;
//	int Sort;
	int SortByData;
	int Increase;
	int NoDuplicate;
	int Own;
	CLinkNode<T> *Exist(CLinkNode<T> *t);
	CLinkNode<T> *Locate(T *t);
	CLinkNode<T> *Locate(T &t);
public:
	unsigned long Count()	{	return count;	}	// get the count of nodes

	CLinkNode<T> *Current()	{	return CurrentNode;	}	// get the current pointer 

	void Current(CLinkNode<T> *t)	{	CurrentNode=Exist(t);	}	// set the current pointer

	void Current(T *t)	{	CurrentNode=Locate(t);	}

	void Current(T &t)	{	CurrentNode=Locate(t);	}

	T *Push(T *item)	{	return Add(item);	}	// add a builded object to top

	T *Push(T &item)	{	return Add(item);	}	// build a new object and add  to top

	T *Pop()		// get the top object and delete it from the link, the object must be destroy by the other 
	{					// object
		T *t=head->data;
		Head();
		Delete();
		return t;
	}

	CLinkNode<T> *GotoNextOf(CLinkNode<T> *from)		// move current pointer to next node of this node
	{
		if ((!from)||(!Exist(from)))
		{
			if (CurrentNode)
				from=CurrentNode;
			else
				return NULL;				
		}
		CurrentNode=from->next;
		return CurrentNode;
	}

	CLinkNode<T> *Next()		// move current pointer to next node
	{
		if (CurrentNode)
		{
			CurrentNode=CurrentNode->next;
			return CurrentNode;
		}
		else
			return NULL;
	}
	CLinkNode<T> *NextIs()
	{
		if (CurrentNode)
			return CurrentNode->next;
		else
			return NULL;
	}
	T *GetData()				// get current data(object)
	{
		if (CurrentNode)
			return CurrentNode->data;
		else
			return NULL;
	}

	CLinkNode<T> *Head()					// move current pointer to begining of link
	{
		CurrentNode=head;
		return CurrentNode;
	}

	CLinkNode<T> *NewLoop()		// mark the current location as the border location of loop
	{
		if (CurrentNode)
			return (LoopMark=CurrentNode);
		else
		{
			CurrentNode=head;
			return (LoopMark=head);
		}
	}

	CLinkNode<T> *LoopNext()
	{
		if (CurrentNode->next)
			CurrentNode=CurrentNode->next;
		else
			CurrentNode=head;
		if (CurrentNode==LoopMark)	// when return to loop mark, a loop terminal
			return NULL;				// this function report terminal only one time, the next call will start another loop
	}

	CLinkNode<T> *Tail()		// move current pointer to end of link
	{
		if (!tail)			// the first time call this funtion , this section should be excuted
		{			
			CLinkNode<T> *p1=head,*p2=NULL;
			while(p1)
			{
				p2=p1;
				p1=p1->next;
			}
			tail=p2;
		}
		CurrentNode=tail;
		return tail;
	}
	
	CLink(int O,bool NoDupl=false, bool sortbydata=true,bool SortIncrease=true)
	{
		head=NULL;
		tail=NULL;
		CurrentNode=NULL;
		Own=O;
		count=0;
		NoDuplicate=NoDupl;
		Increase=SortIncrease;
		SortByData=sortbydata;
	}

	~CLink()	{	ClearAll();	}

	void ClearAll();			// clear the link( reset all )
	void Delete();		// delete the current node
	T *Search(T &t);		// compare the data
	T *Search(T *t);		// compare pointer only
	T *Append(T *item);	// Add a item to the end; point to version
	T *Append(T &item);	// Add a item to the end; copy version
	T *Insert(T *item);	// Insert an item behide CurrentNode;
	T *Insert(T &item);	// Insert an item behide CurrentNode;
	T *Add(T *item);		// Add an item to the head;
	T *Add(T &item);		// Add an item to the head;
	T *SortAdd(T *item);	// point to version , sort by data
	T *SortAdd(T &item);	// copy version , sort by data
	int operator==(CLink<T> &right);	// compare to judge if is equal
	int operator^(CLink<T> &right);		// subtrate function for sort
	unsigned long operator&&(CLink<T> &right);	// return the count of the same section, compare only by the pointer
	friend CLink operator&(CLink &link1,CLink &link2);			// return the same section of them, compare only by the pointer
	CLink &operator=(CLink &link2);		
	CLink(CLink &link2);			// copy constructor , copy pointer only, the data will not be copy
	T *operator->()
	{
		if (CurrentNode)
			return CurrentNode->data;
		else
			return NULL;
	}
};

/*************************************
						Private use only
  ****************************************/
template<class T> CLinkNode<T> *CLink<T>::Locate(T *t)
{
	CLinkNode<T> *p=head;
	while(p)
	{
		if (p->data==t)
			return p;
		p=p->next;
	}
	return NULL;
}

/*************************************
						Private use only
  ****************************************/
template<class T> CLinkNode<T> *CLink<T>::Locate(T &t)
{
	CLinkNode<T> *p=head;
	while(p)
	{
		if (*(p->data)==t)
			return p;
		p=p->next;
	}
	return NULL;
}

/*************************************
						Private use only
  ****************************************/
template<class T> CLinkNode<T> *CLink<T>::Exist(CLinkNode<T> *t)
{
	CLinkNode<T> *p=head;
	while(p&&(p!=t))
	{
		p=p->next;
	}
	return p;
}

template<class T>T *CLink<T>::Search(T &t)		// compare the data
	{
		CLinkNode<T> *p=head;
		while(p)
		{
			if (*(p->data)==t)
				return p->data;
			p=p->next;
		}
		return NULL;
	}

template<class T>T *CLink<T>::Search(T *t)		// compare pointer only
	{
		CLinkNode<T> *p=head;
		while(p)
		{
			if (p->data==t)
				return p->data;
			p=p->next;
		}
		return NULL;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Append(T *item)	// Add a item to the end; point to version
	{
		if (NoDuplicate)
		{
			T *i=Search(*item);
			if (i)	return i;
		}
		register CLinkNode<T> *p=new CLinkNode<T>(Own,item);
		assert(p);
		if (!tail)	Tail();
		if (tail)	tail->next=p;
		if (!head)	head=p;
		tail=p;
		count++;
		return p->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Append(T &item)	// Add a item to the end; copy version
	{
		if (NoDuplicate)
		{
			T *i=Search(item);
			if (i)	return i;
		}
		register CLinkNode<T> *p=new CLinkNode<T>(item,NULL);
		assert(p);
		if (!tail)	Tail();
		if (tail)	tail->next=p;
		if (!head)	head=p;
		tail=p;
		count++;
		return p->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Insert(T *item)	// Insert an item behide CurrentNode;
	{
		if (NoDuplicate)
		{
			T *i=Search(*item);
			if (i)	return i;
		}
		if (!CurrentNode)
			CurrentNode=head;
		CLinkNode<T> *p;
		if (CurrentNode)
		{
			p=new CLinkNode<T>(Own,item,CurrentNode->next);
			assert(p);
			CurrentNode->next=p;
		}
		else		// if the link there is nothing 
		{
			p=new CLinkNode<T>(Own,item);
			assert(p);
			head=p;
			CurrentNode=p;
		}
		count++;
		return p->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Insert(T &item)	// Insert an item behide CurrentNode;
	{
		if (NoDuplicate)
		{
			T *i=Search(item);
			if (i)	return i;
		}
		if (!CurrentNode)
			CurrentNode=head;
		CLinkNode<T> *p;
		if (CurrentNode)
		{
			p=new CLinkNode<T>(item,CurrentNode->next);
			assert(p);
			CurrentNode->next=p;
		}
		else 
		{
			p=new CLinkNode<T>(item);
			assert(p);
			CurrentNode=p;
		}
		count++;
		return p->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Add(T *item)		// Add an item to the head;
	{
		if (NoDuplicate)
		{
			T *i=Search(*item);
			if (i)	return i;
		}
		head=new CLinkNode<T>(Own,item,head);	// use it directly
		assert(head);
		count++;
		return head->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::Add(T &item)		// Add an item to the head;
	{
		if (NoDuplicate)
		{
			T *i=Search(item);
			if (i)	return i;
		}
		head=new CLinkNode<T>(item,head);	// use it directly
		assert(head);
		count++;
		return head->data;
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::SortAdd(T *item)	// point to version 
	{
		if (head==NULL)
		{
			return Add(item);
		}
		CLinkNode<T> *p=head;
		CLinkNode<T> *p2=NULL;
		while(p)
		{
			int b;
			if (SortByData)
				b=*(p->data)-*item;
			else
				b=p->data-item;// sort by pointer
			if ((NoDuplicate)&&(b==0))
				return p->data;
			if (!Increase)
				b=(b>0)?-1:1;
			if (b>0)
			{
				if (p2)
				{
					Current(p2);
					return 	Insert(item);
				}
				else
					return Add(item);
			}
			p2=p;
			p=p->next;
		}
		return Append(item);
	}

/**************************************
				Functions to Add object to link
**************************************/
template<class T>T *CLink<T>::SortAdd(T &item)	// copy version , add orderly by data 
	{
		CLinkNode<T> *p=head;
		CLinkNode<T> *p2=NULL;
		while(p)
		{
			int b=*(p->data)-item;			// compare by data
			if ((NoDuplicate)&&(b==0))
				return p->data;
			if (!Increase)
				b=(b>0)?-1:1;
			if (b>0)
			{
				if (p2)
				{
					Current(p2);
					return 	Insert(item);
				}
				else
					return Add(item);
			}
			p2=p;
			p=p->next;
		}
		return Append(item);
	}

/**************************************
				Destroy functions
**************************************/
template<class T>void CLink<T>::ClearAll()			// clear the link( reset all )
	{
		CLinkNode<T> *p1=head,*p2=head;
		while(p2!=NULL)
		{
			p1=p2->next;
			delete p2;
			p2=p1;
		}
		count=0;
		head=NULL;
		tail=NULL;
		CurrentNode=NULL;
		LoopMark=NULL;
	}

/**************************************
				Destroy functions
**************************************/
template<class T> void CLink<T>::Delete()		// this function is not a effective function because of the
{															// structure of link , don't use it frequently 
	CLinkNode<T> *p1=head,*p2=NULL;
	while(p1&&(p1!=CurrentNode))
	{
		p2=p1;
		p1=p1->next;
	}
	if (p1&&p2)		// if found the node
	{
		p2->next=p1->next;	// get rid of the node
		if (p2->next)
			CurrentNode=p2->next;	// adjust current location to the next
		else
			CurrentNode=p2;			// if reach the tail 
		count--;
		delete p1;
	}
	else if (p1)
	{
		head=p1->next;
		count--;
		delete p1;
	}
	else
		head=tail=CurrentNode=NULL;
}

/**************************************
				Compare functions
**************************************/
template<class T>int CLink<T>::operator==(CLink<T> &right)
	{
		if (SortByData)
		{
			CLinkNode<T> *p1=head,*p2=right.head;
			while(p1&&p2&&(*(p1->data)==*(p2->data)))		// compare by data
			{
				p1=p1->next;
				p2=p2->next;
			}
			return ((p1)&&(p2));
		}
		else
		{
			CLinkNode<T> *p1=head,*p2=right.head;
			while(p1&&p2&&(p1->data==p2->data))						// and here is "compare by pointer"
			{
				p1=p1->next;
				p2=p2->next;
			}
			return ((p1)&&(p2));
		}
	}


/**************************************
				Compare functions
**************************************/
template<class T>int CLink<T>::operator^(CLink<T> &right)
{
		int a=0;
		if (SortByData)
		{
			CLinkNode<T> *p1=head,*p2=right.head;
			while(p1&&p2&&(!(a=*(p1->data)-*(p2->data))))
			{
				p1=p1->next;
				p2=p2->next;
			}
			return a;
		}
		else
		{
			CLinkNode<T> *p1=head,*p2=right.head;
			while(p1&&p2&&(!(a=p1->data-p2->data)))
			{
				p1=p1->next;
				p2=p2->next;
			}
			return a;
		}
}

template<class T> unsigned long CLink<T>::operator&&(CLink<T> &right)		// get the same part of the two link and return the count, compared by pointers
{
	CLinkNode<T> *p=head;
	unsigned long count=0;
	while(p)
	{
		if (right.Search(p->data))
			count++;
		p=p->next;
	}
	return count;
}

template<class T> CLink<T>::CLink<T>(CLink<T> &link2)	// copy constructor , copy pointer only , the data will not be duplicated
{
	head=NULL;
	tail=NULL;
	CurrentNode=NULL;
	Own=0;
	count=0;
	NoDuplicate=link2.NoDuplicate;
	Increase=link2.Increase;
	SortByData=link2.SortByData;
	for (CLinkNode<T> *p=link2.head;p;p=p->next)
	{
		Append(p->data);
	}
}

template<class T>CLink<T> &CLink<T>::operator=(CLink<T> &link2)
{
	ClearAll();
	head=NULL;
	tail=NULL;
	CurrentNode=NULL;
	Own=0;
	count=0;
	NoDuplicate=link2.NoDuplicate;
	Increase=link2.Increase;
	SortByData=link2.SortByData;
	for (CLinkNode<T> *p=link2.head;p;p=p->next)
	{
		Append(p->data);
	}
	return *this;
}

template<class T>CLink<T> operator&(CLink<T> &link1,CLink<T> &link2)			// return the same section of them, compare only by the pointer
{																				// it's a friend function 
	CLink<T> result(/*own=*/false);
	link2.Head();
	T *data;
	for (data=link2.GetData();data;link2.Next(),data=link2.GetData())
	{
		if (link1.Search(data))
			result.Append(data);
	}
	return result;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -