迭代器 ------------如何使用迭代器(list)
一 引出迭代器:了解容器list ,就应该先会用容器list.首先我们要知道list,其实就是一个用模板实现的双向带头循环列表。肯定会有同学有疑问,那既然是个双向带头循环链表,那为什莫要用STL中容器list,#pragma once#include<iostream>using namespace std;#include<list>v
·
一 引出迭代器:
了解容器list ,就应该先会用容器list.首先我们要知道list,其实就是一个用模板实现的双向带头循环列表。
肯定会有同学有疑问,那既然是个双向带头循环链表,那为什莫要用STL中容器list,
#pragma once
#include<iostream>
using namespace std;
#include<list>
void test_list()
{
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
}
看上面这段代码:list它有和之前博客中写到的链表可以完成push_pack这个功能,那它的优点何在?
请思考比如你要打印这些插入的结点,之前的双向循环链表你写一个print()函数就可以,遍历一遍链表就可以。可是这就有很大的问题,你必须知道头结点,不然你怎么遍历,怎么结束呢?但是这就出现了以下缺点:
1.破坏封装 2.增加使用成本
因此在vector中引入了迭代器,用迭代器来访问容器vector的数据
迭代器:(iterator)可在容器上遍访的接口,设计人员无需关心容器物件的内容(减少使用成本)它可以把抽象的容器和通用算法有机的统一起来。迭代器是一种对象,它能够用来遍历标准模板库容器中的部分或全部成员。每个迭代器对象代表容器中的确定的地址。
二 迭代器分类:
#pragma once
#include<iostream>
using namespace std;
#include<list>
void test_list()
{
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
void print_list(const list<int>& l);
//void print_list1(list<int>& l);
//list<int>::iterator it = l1.begin();//遍历链表
//while (it != l1.end())
//{
// cout << *it << " ";
// it++;
//}
//cout << endl;
/
//size_t n = 10;//如果有n个结点,打印n个。没有n个结点,全部打印
//list<int>::iterator it = l1.begin();
//while (it != l1.end() && n--)
//{
// cout << *it << " ";
// it++;
//}
//cout << endl;
//
//list<int>::reverse_iterator rit = l1.rbegin();//反向迭代器 打印出来是倒序的
//while (rit != l1.rend())
//{
// cout << *rit << " ";
// rit++;
//}
//cout << endl;
//
print_list(l1);//掉const迭代器
//print_list1(l1);//掉普通迭代器
}
//void print_list1( list<int>& l) //最好传引用,不然深拷贝代价太大
//{
// list<int>::iterator it = l.begin();//普通迭代器 可读可写
// while (it != l.end())
// {
// if (*it % 2)
// {
// *it = *it * 2;
// cout << *it << " ";
// }
// ++it;
// }
//}
void print_list(const list<int>& l) //最好传引用,不然深拷贝代价太大
{
list<int>::const_iterator it = l.begin(); //const迭代器 只能读不能写
while (it != l.end())
{
if (*it % 2)
{
//*it = *it * 2; const类型不能改变值,只能访问
cout << *it << " ";
}
++it;
}
}
三 迭代器失效问题:
1. 看如下代码:
list<int>::iterator it = l1.begin();//本意是相删除所有偶数
while (it != l1.end())
{
if (*it % 2)
{
l1.erase(it);
}
cout << *it << " ";
it++;
}
看着代码也没有什么问题,但是程序崩溃了,原因就是出现了迭代器失效。
2. 如何解决呢?
其实容器list 里面erase()有一个返回值,返回的是指向下一个结点的迭代器
while (it != l1.end())
{
if (*it % 2)
{
it=l1.erase(it);
}
else
{
cout << *it << " ";
it++;
}
}
删除一个结点,让it接受下,也就是it现在是指向下个结点。
四 总结:1.传统双向链表中,print 是遍历全部打印 ,还要给出头结点 (破坏封装) ---------相当于打包--------不能改变结点
迭代器:可以改变结点,也可以打印部分结点
2.print如果访问,必须知道要访问的数据叫date,然后打印 . -------------增加使用成本
迭代器:不用管你是date,还是x .我*it 就行
更多推荐
已为社区贡献1条内容
所有评论(0)