C++実現の簡易チェーンテーブル

6401 ワード

class ostream;
#include<iostream>
using std::cout;
template <typename T>
struct Node
{
    T data;
    Node<T> *pNext;
};

template <typename T>
class SList
{
public:
    SList();
    ~SList();
private:
    Node<T> *pHead;
	Node<T> *pLast;
    int listSize;
private:
	Node<T>* getNodeAddr(int pos);
public:
    SList<T>& addItem(const T& d);
    void remove(int pos);
	void insert(int pos,const T& value);
	SList<T>& push_front(const T& d);
    const T& at(int pos) const;
	int size() const;
	int indexOf(const T& d) const;
	int count(const T& d)const;
	void reverse();
	void replace(int pos,const T& value);
	void swap(int i,int j);
	const T& first();
	const T& last();
	bool contains(const T& value) const;
	bool startWith(const T& value) const;

	//operator
	SList<T>& operator+=(const SList& list);
	T& operator[](int pos);
	//friend
	friend ostream&operator<<(ostream& os,SList<T>);
};


//  

//private
template <typename T>
Node<T>* SList<T>::getNodeAddr(int pos)
{
	if(pos>=listSize||pos<0)
	{
		return NULL;
	}
	Node<T>* pPos=pHead;
	for(int i=0;i<pos;++i)
	{
		pPos=pPos->pNext;
	}
	return pPos;
}

//  

template <typename T>
SList<T>::SList()
{
    listSize=0;
    pHead=NULL;
    pLast=NULL;
}

template <typename T>
SList<T>::~SList()
{
    if(pHead)
    {
        return;
    }
    Node<T>* pNode=NULL;
    Node<T>* pPre=NULL;
    for(int i=0;pNode;++i)
    {
        pPre=pNode;
        pNode=pNode->pNext;
        delete pPre;
    }
}

template <typename T>
SList<T>& SList<T>::addItem(const T& d)
{
    if(!listSize)
    {
        pHead=new Node<T>;
		pHead->pNext=NULL;
		pHead->data=d;
        pLast=pHead;
        ++listSize;
    }
    else
    {
        Node<T> *pNode=new Node<T>;
        pNode->data=d;
        pNode->pNext=NULL;
        pLast->pNext=pNode;
        pLast=pNode;
		++listSize;
	}
	return *this;
}

template <typename T>
const T& SList<T>::at(int pos) const
{
    T* pData=&(pHead->data);
    Node<T>* pNode=pHead;
    for(int i=0;i<pos;++i)
    {
        pNode=pNode->pNext;
        pData=&(pNode->data);
    }
    return *pData;
}

template <typename T>
int SList<T>::size() const
{
	return listSize;
}

template <typename T>
void SList<T>::remove(int pos)
{
	if(pos+1>listSize||pos<0)
	{
		return;
	}

	Node<T>* pPre=pHead;
	Node<T>* pMid=pHead;
	Node<T>* pNext=pMid->pNext;

	for(int i=0;i<pos;++i)
	{
		pPre=pMid;
		pMid=pMid->pNext;
		pNext=pMid->pNext;
	}

	if(NULL==pNext)
	{
		delete pMid;
		pPre->pNext=NULL;
		pLast=pPre;
	}
	else
	{
		if(pPre==pMid)
		{
			delete pMid;
			pHead=pNext;
			--listSize;
			return;
		}
		delete pMid;
		pPre->pNext=pNext;
	}

	--listSize;
}

template <typename T>
void SList<T>::insert(int pos,const T& value)
{
		if(pos+1>listSize||pos<0)
	{
		return;
	}

	Node<T>* pPre=pHead;
	Node<T>* pMid=pHead;
	Node<T>* pNext=pMid->pNext;

	if(pos+1==listSize)
	{
		Node<T> *pNew=new Node<T>;
		pNew->data=value;
		pNew->pNext=NULL;
		pLast->pNext=pNew;
		pLast=pNew;
	}
	else
	{
		Node<T>* pPos=this->getNodeAddr(pos);
		Node<T>* pNext=pPos->pNext;
		Node<T>* pNew=new Node<T>;
		pNew->data=value;
		pPos->pNext=pNew;
		pNew->pNext=pNext;
	}
	++listSize;
}

template <typename T>
SList<T>& SList<T>::push_front(const T &d)
{
	Node<T>* pNew=new Node<T>;
	pNew->data=d;
	pNew->pNext=pHead;
	pHead=pNew;
	++listSize;
	return *this;
}

template <typename T>
int SList<T>::indexOf(const T &d) const
{
	Node<T>* pPos=pHead;
	int count=0;

	while(pPos)
	{
		if(pPos->data==d)
		{
			return count;
		}
		++count;
		pPos=pPos->pNext;
	}
	return -1;
}

template <typename T>
int SList<T>::count(const T&d) const
{
	Node<T>* pPos=pHead;
	int iCount=0;

	while(pPos)
	{
		if(pPos->data==d)
		{
			++iCount;
		}
		pPos=pPos->pNext;
	}

	return iCount;
}

template <typename T>
void SList<T>::reverse()
{
	if(listSize<=1)
	{
		return;
	}
	else
	{
		Node<T>* pPre=pHead;
		Node<T>* pMid=pHead->pNext;
		Node<T>* pNext=pMid->pNext;

		while(pNext)
		{
			pMid->pNext=pPre;

			pPre=pMid;
			pMid=pNext;
			pNext=pNext->pNext;
		}

		pMid->pNext=pPre;

		Node<T>* pTemp;
		pHead->pNext=NULL;
		pTemp=pHead;
		pHead=pMid;
		pLast=pTemp;
	}
}

template <typename T>
void SList<T>::replace(int pos, const T &value)
{
	Node<T>* pPos=this->getNodeAddr(pos);
	if(pPos)
	{
		pPos->data=value;
	}
}

template <typename T>
void SList<T>::swap(int i,int j)
{
	Node<T>* pPos1=this->getNodeAddr(i);
	Node<T>* pPos2=this->getNodeAddr(j);

	if(pPos1&&pPos2)
	{
		T temp;
		temp=pPos1->data;
		pPos1->data=pPos2->data;
		pPos2->data=temp;
	}
}

template <typename T>
const T& SList<T>::first()
{
	return pHead->data;
}

template <typename T>
const T& SList<T>::last()
{
	return pLast->data;
}

template <typename T>
bool SList<T>::contains(const T&value) const
{
	Node<T>* pPos=pHead;

	while(pPos)
	{
		if(pPos->data==value)
		{
			return true;
		}
		pPos=pPos->pNext;
	}

	return false;
}

template <typename T>
bool SList<T>::startWith(const T&value)const
{
	return pHead->data==value?(true):(false);
}

//operator
template <typename T>
SList<T>& SList<T>::operator+=(const SList<T> &list)
{
	if(list.size()==0)
	{
		return *this;
	}
	listSize+=list.listSize;
	pLast->pNext=list.pHead;
	return *this;
}

template <typename T>
T& SList<T>::operator[](int pos)
{
	Node<T>* pPos=this->getNodeAddr(pos);
	return pPos->data;
}

//friend
template <typename T>
ostream& operator<<(ostream& os,SList<T>& list)
{
	Node<T>* pPos=list.pHead;
	while(pPos)
	{
		os<<pPos->data;
		pPos=pPos->pNext;
	}
	return os;
}