单链表:它是一种链式存储的线性表,用一组地址任意的存储单元存放线性表
的数据元素,称存储单元为一个节点。
单链表中的一个节点分为两个部分,一个存储数据的数据域,一个指向下一个节点的指针域。
单链表又分为无头节点的单链表和带头节点的单链表。
需要注意的是我们在插入Insert,删除Remove,查询Find的时候。我们要时刻注意指针是否非法操作,在没有判断当前指针cur是否为NULL时,直接判断cur->next为NULL,可能直接就会访问出错,导致程序崩溃。
下面代码实现的是带头单链表
template<class T>
struct ListNode
{
ListNode(const T& data)
:_next(NULL)
, _data(data)
{}
T _data;
ListNode* _next;
};
template<class T>
class List
{
typedef ListNode<T> Node;
public:
List()
:_HeadNode(NULL)
, _TailNode(NULL)
{}
void PushBack(const T& data);
void PushFront(const T& data);
void PopFront();
void PopBack();
void Insert(Node* pos,const T& data);
void Remove(Node* pos);
Node* Find(const T& data);
void Printf();
~List();
void destory(Node* ptr);
private:
Node* _HeadNode;
Node* _TailNode;
};
template<class T>
inline void List<T>::PushBack(const T& data)
{
if (NULL == _HeadNode)
{
_HeadNode = _TailNode = new Node(data);
}
else
{
_TailNode->_next = new Node(data);
_TailNode = _TailNode->_next;
}
}
template<class T>
inline void List<T>::PushFront(const T& data)
{
if (!_HeadNode)
_HeadNode = _TailNode = new Node(data);
else
{
Node* tmp = _HeadNode;
_HeadNode = new Node(data);
_HeadNode->_next = tmp;
}
}
template<class T>
inline void List<T>::PopBack()
{
if (!_HeadNode)
return;
Node* cur = _HeadNode;
if (!cur)
{
delete cur;
_HeadNode = _TailNode = NULL;
}
else
{
while (cur->_next != _TailNode)
{
cur = cur->_next;
}
delete cur->_next;
cur->_next = NULL;
_TailNode = cur;
}
}
template<class T>
inline void List<T>::PopFront()
{
assert(_HeadNode);
Node* cur = _HeadNode;
_HeadNode = _HeadNode->_next;
if (!_HeadNode)
_TailNode = _HeadNode;
delete cur;
cur = NULL;
}
template<class T>
inline void List<T>::Insert(Node* pos,const T& data)
{
if (pos == _HeadNode)
PushFront(data);
else if(pos == _TailNode)
PushBack(data);
else
{
Node* tmp = _HeadNode;
Node* pre = _HeadNode;
while (tmp)
{
pre = tmp;
tmp = tmp->_next;
if (pos == tmp)
{
Node* cur = new Node(data);
pre->_next = cur;
cur->_next = tmp;
}
}
}
}
template<class T>
inline void List<T>::Remove(Node* pos)
{
assert(_HeadNode);
if (pos == _HeadNode)
PopFront();
else if(pos == _TailNode)
PopBack();
else
{
Node* tmp = _HeadNode;
Node* pre = _HeadNode;
while (tmp->_next)
{
pre = tmp;
tmp = tmp->_next;
if (tmp == pos)
{
pre->_next = tmp->_next;
delete tmp;
tmp = NULL;
return;
}
}
}
}
template<class T>
typename List<T>::Node* List<T>::Find(const T& data)
{
if (!_HeadNode)
return NULL;
Node* cur = _HeadNode;
while (cur)
{
if (data == cur->_data)
return cur;
cur = cur->_next;
}
return NULL;
}
template<class T>
inline void List<T>::Printf()
{
Node* cur = _HeadNode;
while (cur)
{
cout << cur->_data << " ";
cur = cur->_next;
}
cout << endl;
}
template<class T>
inline List<T>::~List()
{
if (_HeadNode)
{
destory(_HeadNode);
}
}
template<class T>
inline void List<T>::destory(Node* ptr)
{
if (ptr)
{
destory(ptr->_next);
delete ptr;
ptr = NULL;
}
_HeadNode = _TailNode = NULL;
}