尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

C++——list

C++——list 一、基本概念list就是带头的循环双向链表模板类。它的迭代器是双向迭代器不支持[ ]的重载和用/-随机访问数据。1三、常用接口构造、迭代器、empty、size、front、back、不支持[ ]重载、assign、push_front、pop_front、push_back、pop_back、insert、erase、swap、resize、clear、、、、、、迭代器不是原生指针由于物理上内存不是连续的所以不能通过迭代器 e 来访问下一个位置的元素二、迭代器的分类1按照性质进行分类①输入/只读迭代器Input Iterator输入迭代器又叫只读迭代器。类似于一个只能读数据不能修改数据仅支持不支持--的指针。通常用于单向向后遍历。②输出/只写迭代器Output Iterator输出迭代器又叫只写迭代器。类似于一个只能写数据不能读取数据仅支持不支持--的指针。通常用于从单向向后写入。③前向迭代器/单向(读写)迭代器Forward Iterator输出迭代器又叫只写迭代器。类似于一个可以读可写数据仅支持不支持--的指针。通常用于从单向向后遍历写入。和只读迭代器一样要想修改某个位置的数据只能通过遍历去修改这里以forward_list(不带头的不循环的单向链表类模板)。由于单链表在物理结构上不是连续的(遍历时不能使用/-不能通过下标访问某个节点的数据)而且不能往回遍历(不能使用--)。所以在设计它的迭代器时也就设计成了前向迭代器。下面用具体的代码感受一下#includeiostream #includeforward_list using namespace std; //单向迭代器 int main() { forward_listint f{1,2,3}; forward_listint::iterator it f.begin(); cout *it endl;//可读 it;//仅支持 cout *it endl;//可写 //--it;//不支持--会报错 }④双向迭代器/双向读写迭代器(Bidirectional Iterator)双向迭代器又叫做双向读写迭代器。类似于一个可以读可写数据支持/--的指针。通常用于从双向遍历和写入。和只读迭代器一样要想修改某个位置的数据只能通过遍历去修改由于list带头双向循环链表的设计所以它的迭代器也就设计成了双向迭代器。⑤随机访问迭代器(Random Access Iterator)随机访问迭代器又叫做随机读写迭代器。类似于一个可以读可写数据既支持、--还支持加减整数、下标访问、大小比较的指针。即能双向遍历也可以通过下标随机访问数据类似于顺序表。string和vector的底层是数组。根据这种结构string和vector的迭代器就被设计成了随机访问迭代器。string迭代器vector迭代器2迭代器按照功能进行分类迭代器按照功能共有四种。分别是普通迭代器和反向迭代器以及他们的const版本——普通只读迭代器普通反向迭代器。三、list常用接口1构造①无参的默认构造创建一个空的list(仅带哨兵位)。int main() { listint l;//调用默认构造 }②填充构造创建n个值为val的list。int main() { listint l(5,0);//填充构造 for (auto e : l) { cout e -; } cout endl; }③迭代器范围构造用迭代器进行构造但是需要注意list的迭代器是双向迭代器。不支持/-仅支持/--int main() { listint l1(10,0);//填充构造 //listint l2(l1.begin(),l1.begin() 3);//错误写法list迭代器是双向读写迭代器 auto last l1.begin(); last; last; last; listint l2(l1.begin(), last);//迭代器构造 for (auto e : l2) { cout e -; } cout endl; }④拷贝构造用另一个list实例化对象实例化另一个对象。int main() { listint l1(5, 1); listint l2(l1);//拷贝构造 for (auto e : l2) { cout e -; } cout endl; }2empty判断链表是否为空链表为空输出1不为空输出0int main() { listint l1; listint l2(5, 0); cout l1.empty() endl; cout l2.empty() endl; }3size计算链表中的节点个数。int main() { listint l(100, 0); cout l.size() endl; }4front和back①front返回list中的第一个元素的引用。reference是list中节点的引用。②back返回list中最后一个元素的引用。int main() { listint l{10,20,30}; cout l.front() endl; cout l.back() endl; }5assign清空原list并重新对它进行初始化工作。可以形象的理解为先调clear再调对应的构造。int main() { listint l1(3, 0); listint l2{1,2,3,4,5}; l1.assign(l2.begin(), l2.end());//使用迭代器范围接口 Print(l1); l1.assign(5,0);//使用填充接口 Print(l1); l1.assign({10,20,30});//使用初始化列表接口C11引入 Print(l1); }6push_front/pop_front头插和头删。void Print(listint l) { for (auto e : l) { cout e -; } cout endl; } int main() { listint l(3, 0); l.push_front(100);//头插 Print(l); l.pop_front();//头删 Print(l); }7push_back/pop_back尾插和尾删void Print(listint l) { for (auto e : l) { cout e -; } cout endl; } int main() { listint l(3, 0); l.push_back(100);//尾插 Print(l); l.pop_back();//尾删 Print(l); }8insert①next(C11引入)使用时必须包含头文件iterator功能list的迭代器是一个双向迭代器无法直接访问某个数据只能一步步的或者--。而设计next就是实现了多次的。函数原型解释它有两个参数第一个参数是当前位置的迭代器第二个参数是要移动的步数缺省值为1。返回值类型为当前迭代器的类型#includeiostream #includelist #includeiterator using namespace std; int main() { listint l1{10,20,30,40,50}; listint l2(l1.begin(),next(l1.begin(),3));//迭代器构造 for (auto e : l2) { cout e -; } cout endl; }②insert在指定位置插入之前数据。在迭代器指向的元素之前插入数据void Print(listint l) { for (auto e : l) { cout e -; } cout endl; } int main() { listint l1{10,20,30,40,50}; l1.insert(next(l1.begin(),2),100);//在某个位置插入单个元素迭代器指向的是30这个节点100在30之前插入 Print(l1); listint l2{ 10,20,30,40,50 }; l2.insert(l2.begin(),3,100);//在某个位置插入n个val迭代器指向的是20这个节点100在20之前插入 Print(l2); listint l3{ 10,20,30,40,50 }; listint l4(3,0); l3.insert(l3.begin(),l4.begin(),l4.end());//迭代器插入 Print(l3); listint l5{ 10,20,30,40,50 }; l5.insert(l5.begin(), {666,666,666});//初始化列表插入 Print(l5); }9erase删除指定位置的节点。void Print(listint l) { for (auto e : l) { cout e -; } cout endl; } int main() { listint l1{10,20,30,40,50}; l1.erase(next(l1.begin(),2));//删除单个元素 Print(l1); listint l2{ 10,20,30,40,50 }; l2.erase(l2.begin(),--l2.end());//删除迭代器范围内的节点 Print(l2); }10swap交换两个实例化后list对象的内容。int main() { listint l1(5, 0); listint l2(5, 1); cout l1交换前; Print(l1); cout l2交换前; Print(l2); l1.swap(l2); cout l1交换后; Print(l1); cout l2交换后; Print(l2); }11resize调整有效元素的个数。12clear清理节点空间。
返回列表