单链表是一种常见的数据结构,c++不同于C的语言特性是封装、继承和多态。若要实现单链表,首先我们要明确什么是单链表,链表是由一个或多个节点构成的,实现链表的数据结构,我们首先是要明确的是什么是节点。

    节点是由数据+该节点类型的指针组成的,如下:

class SeqNode
{
public:
	friend class SeqList;//定义友元类,使链表类能够访问节点类的私有成员

	SeqNode(DateType data)
		:_data(data),
		_next(NULL)
	{

	}
		
private:
	SeqNode* _next;
	DateType _data;
};

    链表的形成是节点->节点->.....->NULL;

    所以,新手经常不会写链表,解释没有明确节点这种数据结构。有了节点我们便可通过修改节点中的_next指针使其成为链表,这里我们创建出链表类及声明一些链表类的基本操作:

class SeqList
{
public:
	SeqList()//创建链表时,链表中没有任何节点,把头尾指针置空
		:_head(NULL),
		_tail(NULL)
	{

	}
	~SeqList()
	{
		_Clear();
	}
	void PushBack(DateType x);
	void PopBack();
	void PushFront(DateType x);
	void PopFront();
	void Erase(DateType x);
	void Insert(DateType x,size_t pos);
private:
	void _Clear()//用来释放链表每一个节点的函数,对其进行封装,以便实现以后的一些操作
	{
		while (_head)
		{
			SeqNode* _cur = _head;
			_head = _head->_next;
			delete _cur;
		}
	}
	SeqNode*_head;//头指针
	SeqNode*_tail;//尾指针

};

    在这里我没有写出这两个类的拷贝构造以及赋值运算符的重载,链表的复制可以用深浅拷贝两种方式实现,节点的复制是需要看DateType的类型以及所存储内容来决定,例如每个节点都存一个在堆上开辟的字符串,在这里我默认存储为×××,所以并不涉及深浅拷贝的问题。

    其余已声明函数的实现:

#include"SList.h"
#include<cassert>
void SeqList::PushBack(DateType x)
{
	if (_head == NULL)
	{
		_tail=_head = new SeqNode(x);
	}
	else
	{
		_tail->_next = new SeqNode(x);
		_tail = _tail->_next;
	}
}
void SeqList::PopBack()
{
	assert(_head);
	if (_head == _tail)
	{
		delete _head;
		_head = _tail = NULL;
	}
	else
	{
		SeqNode*cur = _head;
		while (cur->_next != _tail)
		{
			cur = cur->_next;
		}
		cur->_next = NULL;
		delete _tail;
		_tail = cur;
	}
}
void SeqList::PushFront(DateType x)
{
	if (_head == NULL)
	{
		_tail = _head = new SeqNode(x);
	}
	else
	{
		SeqNode* cur = new SeqNode(x);
		cur->_next = _head;
		_head = cur;
	}
}
void SeqList::PopFront()
{
	assert(_head);
	if (_head == _tail)
	{
		delete _head;
		_head = _tail = NULL;
	}
	else
	{
		SeqNode*cur = _head;
		_head = _head->_next;
		delete cur;
	}
}
void SeqList::Insert(DateType x, size_t pos)
{
	if (pos == 0||_head == NULL)
	{
		PushFront(x);
	}
	else
	{
		SeqNode*cur = _head;
		SeqNode*tmp = new SeqNode(x);
		while (--pos)
		{
			cur = cur->_next;
		}
		tmp->_next = cur->_next;
		cur->_next = tmp;
	}
}
void SeqList::Erase(DateType x)
{
	while (_head->_data == x)
	{
		SeqNode*tmp = _head;
		_head = _head->_next;
		delete tmp;
	}
	if (_head->_next != NULL)
	{
		SeqNode*prev = _head;
		SeqNode*cur = prev->_next;
		while (cur)
		{
			if (cur->_data == x)
			{
				SeqNode*tmp = cur;
				cur = cur->_next;
				prev->_next = cur;
				delete tmp;
			}
			prev = prev->_next;
			cur = prev->_next;
		}
	}

}

测试用例:

#include<iostream>
using namespace std;
#include"SList.h"
void Test1()
{
	SeqList l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);
	l.PopBack();
	l.PopBack();
	l.PopBack();
	l.PopBack();
	l.PopBack();
	l.PushFront(5);
	l.PushFront(4);
	l.PushFront(3);
	l.PushFront(2);
	l.PushFront(1);
	l.PopFront();
	l.PopFront();
	l.PopFront();
	l.PopFront();
	l.PopFront();
	l.PopFront();	
}
void Test2()
{
	SeqList l;
	l.Insert(1,1);
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(1);
	l.PushBack(6);
	l.Erase(1);
	l.Insert(5, 3);


}
int main()
{
	Test2();
	return 0;
}

    如有不足之处,希望指正。