C++单链表的设计与实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++单链表的设计与实现相关的知识,希望对你有一定的参考价值。
单链表是一种常见的数据结构,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; }
如有不足之处,希望指正。
本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1746921
以上是关于C++单链表的设计与实现的主要内容,如果未能解决你的问题,请参考以下文章
本科课程数据结构与算法实验2——单链表与双向循环链表的插入删除操作(C++实现)