链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
- 链表的组成:链表由一系列结点组成
- 结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
C++STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
今天实现的简单链表如下:
- 链表类Mylist(封装私有成员Node指针head)
- Mylist类头部插入数据:insert_head
- 重载输出符号<<使cout直接输出节点数据
- 节点结构体Node(封装整型数据,结构体指针)
- Mylist类内部封装的迭代器类Iterator
- Iterator类重载++运算符使迭代器可以指向下一个节点
- Iterator类重载*运算符使通过迭代器*拿到节点的数据
- Iterator类重载!=运算符使!=可以比较两个节点对象
- 头部迭代器begin()
- 尾部迭代器end()
没有使用C++模板,下一篇将会使用模板完善Mylist
代码示例:
class Mylist
{
//节点结构体
struct Node
{
Node(int x, Node* ptr = nullptr):data(x),next(ptr) {}
int data;
Node* next;
};
public:
//Mylist类封装的迭代器Iterator
class Iterator
{
public:
Iterator(Node* ptr=nullptr):pos(ptr){}
~Iterator() {}
Iterator &operator++(int) {
if (nullptr != pos) {
pos = pos->next;
}
return *this;
}
int& operator*() {
return pos->data;
}
bool operator !=(Iterator x) {
return pos != x.pos;
}
private:
Node* pos;
};
public:
Mylist() :head(nullptr) {}
~Mylist() {
while (head){
Node* tem = head;
head = head->next;
delete tem;
}
}
//头部插入数据
void insert_head(int data) {
Node* node = new Node(data);
node->next = head;
head = node;
}
//输出<< 符号重载,cout<<直接输出Mylist& list的每一个节点
friend ostream& operator<<(ostream& out, const Mylist& list);
//迭代器头部位置
Iterator begin(){
return Iterator(head);
}
//迭代器尾部位置
Iterator end() {
return Iterator(nullptr);
}
private:
//节点的头指针
Node* head;
};
ostream& operator<<(ostream& out, const Mylist& list) {
Mylist::Node* tem = list.head;
while (tem){
out << tem->data << ",";
tem = tem->next;
}
out << endl;
return out;
}
main函数测试
int main() {
Mylist l1;
l1.insert_head(1);
l1.insert_head(2);
l1.insert_head(3);
l1.insert_head(4);
l1.insert_head(5);
cout << l1;
Mylist::Iterator i = l1.begin();
while (i!=l1.end())
{
cout << *i << endl;
i++;
}
system("pause");
return 0;
}
感谢观看
下一篇将会使用模板完善Mylist