C++单链表的设计与实现
2016-03-02 21:54
483 查看
单链表是一种常见的数据结构,c++不同于C的语言特性是封装、继承和多态。若要实现单链表,首先我们要明确什么是单链表,链表是由一个或多个节点构成的,实现链表的数据结构,我们首先是要明确的是什么是节点。
节点是由数据+该节点类型的指针组成的,如下:
所以,新手经常不会写链表,解释没有明确节点这种数据结构。有了节点我们便可通过修改节点中的_next指针使其成为链表,这里我们创建出链表类及声明一些链表类的基本操作:
其余已声明函数的实现:
节点是由数据+该节点类型的指针组成的,如下:
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; }如有不足之处,希望指正。
相关文章推荐
- C++学习
- java c# ios c++
- C语言内存管理
- GitHub 通告:整理了一个 C 和 C++ 开源库的清单(含示例代码)
- C++基础知识易错点总结(3)
- 九度-题目1088:剩下的树
- c语言实现无向图的邻接表储存
- C++练手之计算老妈的工作时间段
- DSP 2812: 使用C++封装系统时钟管理模块
- <<Effective C++>>读书笔记(一)
- Rational Number.c
- C++内存布局(上)
- C语言注释转换为c++的注释
- C++学习之继承和派生
- 结构体嵌套对齐
- C/C++ 图像二进制存储与读取
- C/C++ 图像二进制存储与读取
- C语言中的文件流的输入和输出
- C语言中"\"的作用
- MFC中数据类型转换的一些心得