链表:是一种线性表,但是并不是顺序存储,而是每个节点里面存储着下一个节点的指针,把存储数据元素的数据串链起来。
链表可分为带头结点的和不带头结点的。
接下来用代码来展示单链表的各个功能:
#include<iostream>
using namespace std;
template<class T>
struct LinkNode
{
LinkNode<T>* _next;
T _data;
LinkNode(const T& x)
:_data(x)
,_next(NULL)
{}
};
template<class T>
class List
{
typedef LinkNode<T> Node;
public:
List()//构造函数
:_head(NULL)
,_tail(NULL)
{}
List(const List<T>& s) //拷贝构造函数
:_head(NULL), _tail(NULL)
{
if (s._head == NULL)
{
return;
}
else
{
Node *cur(s._head);//调用尾插的方法
while (cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
}
~List()//析构函数
{
Node *cur = _head;
while (cur)
{
Node *next = cur->_next;
delete cur;
cur = next;
}
_head = _tail = NULL;
}
void Swap(List<T>& s) //交换函数
{
swap(_head, s._head);
swap(_tail, s._tail);
}
List<T>& operator=(List<T> s) //赋值运算符的重载
{
Swap(s);
return *this;
}
void PushBack(const T& x)//尾插
{
if(_head == NULL)
{
_head = _tail = new Node(x);
}
else
{
Node* cur = new Node(x);
_tail->_next = cur;
_tail = cur;
}
}
void PopBack()//尾删
{
if(_head == NULL)//没有结点
{
cout<<"单链表为空"<<" ";
}
else if(_head->_next == NULL)//有一个结点
{
delete _tail;
_head = _tail = NULL;
}
else
{
Node* tmp = _head;
while(tmp->_next != _tail)
{
tmp = tmp->_next;
}
delete _tail;
_tail = tmp;
_tail->_next = NULL;
tmp = NULL;
}
}
void PushFront(const T& x)//头插
{
if(_head == NULL)
{
Node* cur = new Node(x);
_head = cur;
_tail = cur;
}
else
{
Node* cur = new Node(x);
cur->_next = _head;
_head = cur;
}
}
void PopFront()//头删
{
if(_head == NULL)//没有结点
{
cout<<"单链表为空"<<" ";
}
else if(_head->_next == NULL)//有一个结点
{
delete _tail;
_head = _tail = NULL;
}
else
{
Node* tmp = _head;
tmp = _head->_next;
delete _head;
_head = tmp;
tmp = NULL;
}
}
Node* Find(T x) //查找函数
{
if (_head == NULL)
return NULL;
else
{
Node *cur(_head);
while (cur != NULL)
{
if (cur->_data == x)
{
break;
}
cur = cur->_next;
}
return cur;
}
}
void Insert(Node* pos, T x)//指定位置插入元素
{
if(pos == _head)
{
PushFront(x);
}
else
{
Node* cur = _head;
Node* tmp = new Node(x);
while(cur->_next != pos)
{
cur = cur->_next;
}
cur->_next = tmp;
tmp->_next = pos;
}
}
void Erase(Node* pos) //删除指定元素
{
if(_head == pos)
{
PopFront();
}
else
{
Node* cur(_head);
while (cur->_next != pos)
{
cur = cur->_next;
}
cur->_next = pos->_next;
delete pos;
pos = NULL;
}
}
void Destroy()//销毁单链表
{
if (_head == NULL)
{
_head = _tail = NULL;
}
else
{
Node *cur(_head);
while (cur != NULL)
{
cur = cur->_next;
delete _head;
_head = cur;
}
_head = _tail = NULL;
}
}
Node* Reverse() //单链表的逆置
{
Node* pre = _head;
Node* cur = pre->_next;
Node* next = NULL;
if(_head == NULL || _head->_next ==NULL)
{
return 0;
}
else
{
while(cur != NULL)
{
next = cur->_next;
cur->_next = pre;
pre = cur;
cur = next;
}
_head->_next = NULL;
_head = pre;
return _head;
}
}
void Print()//显示函数
{
if(_head == NULL)
{
cout<<"单链表为空"<<" ";
}
else
{
Node* _cur = _head;
while(_cur)
{
cout<<_cur->_data<<" ";
_cur = _cur->_next;
}
cout<<endl;
}
}
private:
Node* _head;
Node* _tail;
};
void Test()//测试函数
{
List<int> l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(5);
l1.PushFront(0);
//l1.Reverse();
///l1.PopBack();
//l1.PopFront();
//List<int> l2;
//l2.operator = l1;
//l2 = l1;
//l2.Print();
l1.Print();
}
int main()
{
Test();
return 0;
}
对于单链表的逆置我会在下面的文章里详细介绍实现。