您的位置:首页 > 编程语言 > C语言/C++

C++单链表的设计与实现

2016-03-02 21:54 483 查看
单链表是一种常见的数据结构,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;
}
如有不足之处,希望指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息