#include<iostream>
#include<sstream>
#include<string>
#include"linearList.h"
#include"chainNode.h"
#include"exception.h"
using namespace std;
template<class T>
class chain :public linearList < T >
{
public:
//构造函数 复制构造函数 析构函数
chain(int initialCapacity = 10);
chain(const chain<T>&);
~chain();
bool empty() const{ return listSize == 0; }
int size() const{ return listSize; }
T &get(int theIndex) const;
int indexOf(const T &theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(ostream& out)const;
protected:
void checkIndex(int theIndex) const;
chainNode<T> *firstNode;
int listSize;
};
template<class T>
chain<T>::chain(int initialCapacity = 10)
{
if (initialCapacity < 1)
{
ostringstream s;
s << "Initial capacity= " << initialCapacity << "Must be > 0";
throw illegalParameterValue((s.str()));
}
firstNode = NULL;
listSize = 0;
}
template<class T>
chain<T>::chain(const chain<T>& theList)
{//复制构造函数
listSize = theList.listSize;
if (listSize == 0)
{//链表theList为空
firstNode = NULL;
return;
}
//链表theList非空
chainNode<T>* sourseNode = theList.firstNode; //复制链表theList的节点
firstNode = new chainNode<T>(sourseNode->element);//复制链表theList的首元素
sourseNode = sourseNode->next;
chainNode<T>* targetNode = firstNode;
while (sourseNode != NULL)
{
targetNode->next = new chainNode<T>(sourseNode->element);
sourseNode = sourseNode->next;
targetNode = targetNode->next;
}
targetNode->next = NULL;
}
template<class T>
chain<T>::~chain()
{
//删除链表所有节点
while (firstNode != NULL)
{
chainNode<T> *nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template <class T>
void chain<T>::checkIndex(int theIndex) const
{//确定索引的值在0到listSize-1之间
if(theIndex < 0 || theIndex >= listSize)
{
ostringstream s;
s << "index = " << theIndex << " size = " << listSize;
throw illegalIndex(s.str());
}
}
template <class T>
T& chain<T>::get(int theIndex) const
{//返回索引的元素
//不存在则抛出异常
checkIndex(theIndex);
chainNode<T>*currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
{
currentNode = currentNode->next;
}
return currentNode->element;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{
//返回元素theElement首次出现的索引
//若改元素不存在则返回-1;
//从链表搜索元素
chainNode<T> *currentNode = firstNode;
int theIndex = 0;
while (currentNode != NULL&¤tNode->element != theElement)
{
currentNode = currentNode->next;
theIndex++;
}
if (currentNode == NULL)
{
return -1;
}
else
{
return theIndex;
}
}
template<class T>
void chain<T>::erase(int theIndex)
{
//删除索引为theIndex的元素
//若该元素不存在抛出异常
checkIndex(theIndex);
//索引优秀寻找要删除元素的节点
chainNode<T> *deleteNode;
if (theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
}
else
{
chainNode<T> *currentNode = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
currentNode = currentNode->next;//找到要删除节点的前驱
}
deleteNode = currentNode->next; //前驱的下一个节点即为要删除的节点
currentNode->next = currentNode->next->next;//将前驱与后驱链接起来(前驱即待删除元素的前一个元素,后驱即待删除元素的后一个元素)
}
listSize--;
delete deleteNode;
}
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
//在索引theIndex处插入theElement
if (theIndex<0 || theIndex>listSize)
{
ostringstream s;
s << "Index = " << theIndex << "size = " << listSize;
throw illegalIndex(s.str());
}
if (theIndex == 0)
{
//在表头插入
firstNode = new chainNode<T>(theElement, firstNode);
//等价于如下语句:
// chainNode<T> *currentNode = firstNode;
// firstNode = new chainNode<T>();
// firstNode->element = theElement;
// firstNode->next = currentNode;
}
else
{
//寻找索引的前驱
chainNode<T> *currentNode = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
currentNode = currentNode->next;
}
//在currentNode后插入
currentNode->next = new chainNode<T>(theElement, currentNode->next);
//这句代码含义即:
//chainNode<T> *tempNode = new chainNode<T>(theElement);
//tempNode->next = currentNode->next;
//currentNode->next = tempNode;
}
listSize++;
}
template<class T>
void chain<T>::output(ostream& out)const
{
for (chainNode<T>*currentNode = firstNode; currentNode != NULL; currentNode = currentNode->next)
{
out << currentNode->element << " ";
}
}
//重载《《
template<class T>
ostream& operator<<(ostream& out, const chain<T>& X)
{
X.output(out);
return out;
}
chainNode.h
template <class T>
struct chainNode
{
//数据成员
T element;
chainNode<T> *next; //储存下一个节点的指针
//方法
chainNode(){};
chainNode(const T& element)
{
this->element = element;
}
chainNode(const T& element, chainNode<T>* next)
{
this->element = element;
this->next = next;
}
};