#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
using namespace std;
template<class T>
struct LinkNode //链表节点类的定义
{
T data; //数据域
LinkNode<T> *link; //链指针域
LinkNode(LinkNode<T> *ptr = NULL) //仅初始化指针成员的构造函数
{
link = ptr;
}
LinkNode(const T &item,LinkNode<T> *ptr = NULL) //初始化数据与指针成员的构造函数
{
data = item;
link = ptr;
}
};
template<class T> //单链表类定义
class List
{
public:
List()
{
first = new LinkNode<T>;
}
List(const T &x)
{
first = new LinkNode<T>(x);
}
List(List<T> &L);
~List()
{
MakeEmpty();
}
void MakeEmpty(); //将链表置为空表
int Length()const; //计算链表的长度
LinkNode<T> *GetHead()const //返回附加头结点的地址
{
return first;
}
LinkNode<T> *Search(T x)const; //搜索含数据x的元素
LinkNode<T> *Locate(int i)const; //搜索第i个元素的地址
bool GetData(int i,T &x)const; //取出第i个元素的值
bool Insert(int i,T &x); //在第i个元素后插入x
bool Remove(int i,T &x); //删除第i个元素的值,返回该元素的值给x
void InputFront(T endTag); //前插法输入建立单链表
void InputRear(T endTag); //后插法输入建立单链表
void Output(); //输出
void reverse(); //就地逆置
int GetNumber(LinkNode<T> *address); //根据链表结点地址计算位置
protected:
LinkNode<T> *first; //链表的头指针
};
// List类的成员函数的实现 //
//复制构造函数
template<class T>
List<T>::List(List<T> &L)
{
T value;
LinkNode<T> *srcptr = L.GetHead(); //被复制表的附加头结点地址
LinkNode<T> *destptr = first = new LinkNode<T>;
while(srcptr->link != NULL)
{
value = srcptr->link->data;
destptr->link = new LinkNode<T>(value);
destptr = destptr->link;
srcptr = srcptr->link;
}
destptr->link = NULL;
}
//将链表置为空
template<class T>
void List<T>::MakeEmpty()
{
LinkNode<T> *current;
while(first->link != NULL)
{
current = first->link;
first->link = current->link;
delete current;
}
}
//计算带附加头结点的单链表的长度
template<class T>
int List<T>::Length()const
{
LinkNode<T> *current = first->link;
int count=0;
while(current != NULL)
{
++count;
current = current->link;
}
return count;
}
//在表中搜索含数据x的结点,搜索成功时函数返回该结点地址;否则返回NULL值
template<class T>
LinkNode<T> *List<T>::Search(T x)const
{
LinkNode<T> *current = first->link;
while(current != NULL)
{
if(current->data == x)
break;
else
current = current->link;
}
return current;
}
//定位函数:返回表中第i个元素的地址。若i<0或i超出表中结点个数,则返回NULL
template<class T>
LinkNode<T> *List<T>::Locate(int i)const
{
if(i < 0)
return NULL;
LinkNode<T> *current = first;
int k = 0;
while(current != NULL && k < i)
{
current = current->link;
k++;
}
return current; //返回第i个结点地址,若返回NULL,则表示i太大
}
//取出链表中第i个元素的值
template<class T>
bool List<T>::GetData(int i,T &x)const
{
if(i <= 0)
return false; //i值太小
LinkNode<T> *current = Locate(i);
if(current == NULL) //i值太大
return false;
else
{
x = current->data;
return true;
}
}
//将新元素x插入在链表中第i个结点之后
template<class T>
bool List<T>::Insert(int i,T &x)
{
LinkNode<T> *current = Locate(i);
if(current == NULL)
return false;
LinkNode<T> *newNode = new LinkNode<T>(x);
if(newNode == NULL)
{
cerr<<"存储分配错误!"<<endl;
exit(1);
}
newNode->link = current->link;
current->link = newNode;
return true;
}
//将链表中的第i个元素删除,通过引用型参数x返回该元素的值
template<class T>
bool List<T>::Remove(int i,T &x)
{
LinkNode<T> *current = Locate(i-1);
if(current == NULL || current->link == NULL)
return false;
LinkNode<T> *del = current->link; //重新拉链,将被删结点从链中摘下
current->link = del->link;
x = del->data;
delete del;
return true;
}
//单链表的输出函数:将单链表中所有数据按逻辑顺序输出到屏幕上
template<class T>
void List<T>::Output()
{
LinkNode<T> *current = first->link;
while(current != NULL)
{
cout<<current->data<<endl;
current = current->link;
}
}
//前插法输入建立单链表
template<class T>
void List<T>::InputFront(T endTag)
{
LinkNode<T> *newNode;
T val;
MakeEmpty();
cin>>val;
while (val != endTag)
{
newNode = new LinkNode<T>(val);
if (newNode == NULL)
{
cerr<<"存储分配错误!"<<endl;
exit(1);
}
newNode->link = first->link;
first->link = newNode;
cin>>val;
}
}
//后插法输入建立单链表
template<class T>
void List<T>::InputRear(T endTag)
{
LinkNode<T> *newNode,*last;
T val;
MakeEmpty();
cin>>val;
last = first;
while (val != endTag)
{
newNode = new LinkNode<T>(val);
if (newNode == NULL)
{
cerr<<"存储分配错误!"<<endl;
exit(1);
}
last->link = newNode;
last = newNode;
cin>>val;
}
last->link = NULL;
}
//基本线性表的就地逆置
template <class T>
void List<T>::reverse()
{
LinkNode<T> *p = first->link,*current;
first->link = NULL;
while(p != NULL)
{
current = p;
p = p->link;
current->link = first->link;
first->link = current;
}
}
//根据链表结点地址计算位置
template <class T>
int List<T>::GetNumber(LinkNode<T> *address)
{
if(address == NULL)
return -1;
else
{
LinkNode<T> *current = first;
int k=0;
while (current != address)
{
++k;
current = current->link;
}
return k;
}
}
#endif