前情回顾
在上一块石碑中,我学到了queue,同时下一块石碑也显露出来…
🚄上章地址:第九章(6):STL之queue
list
概念
list可以将数据链式存储,list也就是链表,链表是由一系列的节点组成,节点是内部有两块区域,一个是存放下一个节点地址的指针域,一个是存放数据的数据域,链表可以对任意位置进行快速的插入和删除,但是因为链表不是一块连续的空间,所以遍历的速度慢于数组,并且占用空间比数组要大,list的本质就是一个双向循环链表,双向循环列表指的就是,第一个节点记录着最后的位置,最后一个节点记录第一个节点的位置
由于链表的储存方法不是连续空间,所以list的迭代器只支持前移和后移,属于双向迭代器,不能随机访问
优缺点
优点:
采用动态存储分配,不会造成内存的浪费和溢出
list的插入和删除十分方便,只需要修改指针就可以,不需要移动内部的大量数据
list的插入和删除不会造成原有的迭代器失效,而vector不行,因为vector在插入扩展的时候,会找一片新空间将数据拷贝过去,
缺点:
相比较数组而言,链表所占用的空间较大,遍历消耗的额外时间较多
构造函数
list中的构造函数与vector一样,有四个构造函数
list< T >;//;默认构造函数 list(beg,end);//将迭代器beg到end之间的数据拷贝到本身 list(size_t n,T elem);//将n个elem赋值给本身 list(const list &l);//将l的元素拷贝到本身
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { list<int> l; list<int> l1(10, 1); print(l1); list<int>l2(l1); print(l2); list <int>l3(l1.begin(), l1.end()); print(l3); } int main() { test1(); return 0; }
赋值函数
list中的赋值操作与vector中也是一样的,有三种
list& operator=(const list &l);//操作符重载 assign(beg,end);//将迭代器beg到end的数据拷贝到本身 assign(int n,T elem);//将n个elem拷贝到本身
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { list<int> l(10, 1); print(l); list<int> l1; l1 = l; print(l1); list<int> l2; l2.assign(l1.begin(),l1.end()); print(l2); list<int> l3; l3.assign(10, 2); print(l3); } int main() { test1(); return 0; }
交换函数
与vector一样,可以利用swap函数进行交换
swap(list< T > &l);//将l的数据和本身进行交换
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { cout << "交换前" << endl; list<int> l(10, 1); print(l); list<int> l1; l1.assign(10, 2); print(l1); cout << "交换后" << endl; l.swap(l1); print(l); print(l1); } int main() { test1(); return 0; }
容器和大小操作
list比vector少一个容器大小,因为list的空间不是连续的,数据存放方式也与vector不同,有多少元素大小就多少,和vector不一样,所以不需要
size();//返回容器内元素个数 empty();//判断容器是否为空,为空返回真 resize(size_t num);///可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补0,若变短,则将超出的部分全部删除 reszie(size_t num,T elem);//可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补elem,若变短,则将超出的部分全部删除
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { list<int> l; if (l.empty()) { cout << "l为空" << endl; } cout << l.size() << endl; l.assign(10, 1); print(l); l.resize(11); print(l); l.resize(15, 1); print(l); } int main() { test1(); return 0; }
插入操作
list中,有五种插入操作,可以从头部插入,从尾部插入,还有insert的三个重载版本
push_front(T elem);//在头部插入elem push_end(T elem);//在尾部插入elem insert(pos,T elem);//在pos的位置插入一个elem,返回新数据的位置 insert(pos, size_t n,T elem);//在pos位置插入n个elem insert(pos,beg,end);//在pos位置插入迭代器beg到end的数据
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { list<int> l; l.push_back(2); print(l); l.push_front(1); print(l); l.insert(l.end(), 3); print(l); l.insert(l.begin(), 1,0); print(l); list<int>::iterator b = l.begin(); b++; l.insert(b, l.begin(), l.end()); print(l); } int main() { test1(); return 0; }
删除操作
删除操作有六个,向比较vector多了头部的删除,和一个删除一样元素的删除
pop_back();//删除尾部元素 pop_front();//删除头部元素 clear();//删除全部元素 erase(beg,end);//删除迭代器beg到end之间的数据 erase(pos);//删除迭代器pos位置的数据,返回下一个元素的位置 remove(T elem);//删除容器中所有的elem
使用:
#include<iostream> #include<list> using namespace std; void print(list<int>& l) { for (list<int>::iterator b=l.begin(); b != l.end(); b++) { cout << *b << " "; } cout << endl; } void test1() { list<int> l; for (int i = 0; i < 10; i++) { l.push_back(i); l.push_back(i); } print(l); l.pop_back(); print(l); l.pop_front(); print(l); list<int>::iterator b = l.begin(); b++; b++; b++; l.erase(b); print(l); list<int>::iterator b1 = l.begin(); b1++; b1++; b1++; l.erase(b1, l.end()); print(l); l.remove(1); print(l); l.clear(); print(l); } int main() { test1(); return 0; }