博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
List容器
阅读量:6202 次
发布时间:2019-06-21

本文共 9312 字,大约阅读时间需要 31 分钟。

hot3.png

1、List

(1)定义

List是一种序列式容器。List容器完成的功能实际上和数据结构中的双向链表是极其相似的,List中的数据元素是通过链表指针串连成逻辑意义上的线性表,也就是List也具有链表的主要优点,即:在链表的任一位置进行元素的插入、删除操作都是快速的。

(2)底层实现

List的实现大概是这样的,类似双向链表,:list的每个节点有三个域:前驱元素指针域、数据域和后继元素指针域。

前驱元素指针域保存了前驱元素的首地址;数据域则是本节点的数据;后继元素指针域则保存了后继元素的首地址。其实,List和循环链表也有相似的地方,即:头节点的前驱元素指针域保存的是链表中尾元素的首地址,List的尾节点的后继元素指针域则保存了头节点的首地址,这样,List实际上就构成了一个双向循环链。

由于List元素节点并不要求在一段连续的内存中,显然在List中是不支持快速随机存取的,因此对于迭代器,只能通过“++”或“--”操作将迭代器移动到后继/前驱节点元素处。而不能对迭代器进行+n或-n的操作,这点是与vector等不同的地方

(3)使用

使用list容器之前必须加上<list>头文件:#include<list>;

List属于std命名域的内容,因此需要通过命名限定:using std::list;也可以直接使用全局的命名空间方式:using namespace std。

(4)特点

优点:(1)内存不连续

          (2)动态操作,插入与删除效率高;

          (3)可在两端进行pop,push。

缺点:(1)不能随机访问;

          (2)相对于vector占用内存多(需要存储前驱后继元素指针域)

2、成员函数

(1)构造函数

/*构造函数*/list() //声明一个空列表;list(n) //声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的list(n,val) //声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的list(n,val) //声明一个和上面一样的列表list(first,last) //声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素

(2)赋值操作

assign()://具体和vector中的操作类似,也是有两种情况://第一种是:l1.assign(n,val)将 l1中元素变为n个T(val);//第二种情况是:l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1c.assign(n,num);//将n个num拷贝赋值给链表c。c.assign(beg,end);//将[beg,end)区间的元素拷贝赋值给链表c。

示例:

int a[5] = {1,2,3,4,5};    list
 a1;    list
::iterator it;    a1.assign(2,10);    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    a1.assign(a,a+5);    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;

(3)插入操作

push_back();//push_back()从list的末端插入push_front()://push_front()实现的从list的头部插入insert()://在指定位置插入一个或多个元素(三个重载)c.insert(pos,num);//在pos位置插入元素num。c.insert(pos,n,num);//在pos位置插入n个元素num。c.insert(pos,beg,end);//在pos位置插入区间为[beg,end)的元素。

示例:

list
 a1{1,2,3,4,5};    list
::iterator it;    cout << "insert before:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.insert(a1.begin(),0);    cout << "insert(pos,num) after:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.insert(a1.begin(),2,88);    cout << "insert(pos,n,num) after:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    int arr[5] = {11,22,33,44,55};    a1.insert(a1.begin(),arr,arr+3);    cout << "insert(pos,beg,end) after:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,2,3,4,5};    a1.push_back(10);    list
::iterator it;    cout << "push_back:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.pop_back();    cout << "pop_back:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.push_front(20);    cout << "push_front:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.pop_front();    cout << "pop_front:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;

(4)删除操作

pop_back();//通过pop_front()删除第一个元素pop_front()://删除最后一个元素//序列必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。clear(): //清空list中的所有元素。erase()://删除一个元素或一个区域的元素(两个重载)l1.erase(l1.begin()); //将l1的第一个元素删除。l1.erase(l1.begin(),l1.end()); //将l1的从begin()到end()之间的元素删除。remove(num);//删除链表中匹配num的元素remove_if(comp);//删除条件满足的元素,参数为自定义的回调函数unique();//删除相邻的元素

示例:

list
 a1{1,2,3,4,5};    list
::iterator it;    cout << "clear before:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << "\t";    }    cout << endl;    a1.clear();    cout << "clear after:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << "\t";    }    cout << endl;
list
 a1{1,2,3,4,5};    list
::iterator it;    cout << "erase before:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    a1.erase(a1.begin());    cout << "erase after:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,2,3,4,5};    a1.remove(3);    list
::iterator it;    cout << "remove():";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,2,3,4,5};    a1.remove_if([](int n){return n<3;});    list
::iterator it;    cout << "remove_if():";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,1,3,3,5};    a1.unique();    list
::iterator it;    cout << "unique:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    return 0;

(5)定位操作

begin();//通过调用list容器的成员函数begin()得到一个指向容器起始位置的iteratorend():,//调用list容器的 end()函数来得到list末端下一位置,相当于:int a[n]中的第n+1个位置a[n],//实际上是不存在的,不能访问,经常作为循环结束判断结束条件使用。c.rbegin();//返回逆向链表的第一个元素,即c链表的最后一个数据。c.rend();//返回逆向链表的最后一个元素的下一个位置,即c链表的第一个数据再往前的位置。front();//通过front()可以获得list容器中的头部元素back(): ,//通过back()可以获得list容器的最后一个元素//但是有一点要注意,就是list中元素是空的时候,这时候调用front()和back()会发生什么呢?//实际上会发生不能正常读取数据的情况,但是这并不报错,那我们编程序时就要注意了,建议在使用之前最好先调用empty()函数判断list是否为空。reverse()://通过reverse()完成list的逆置。

示例:

list
 a1{1,2,3,4,5};list
::iterator it;for(it = a1.begin();it!=a1.end();it++){cout << *it << "\t";}cout << endl;
list
 a1{1,2,3,4,5};list
::reverse_iterator it;for(it = a1.rbegin();it!=a1.rend();it++){cout << *it << "\t";}cout << endl;
list
 a1{1,2,3,4,5};if(!a1.empty()){cout << "the first number is:" << a1.front() << endl;cout << "the last number is:" << a1.back() << endl;}
list
 a1{1,2,3,4,5};    a1.reverse();    list
::iterator it;    cout << "reverse:";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;

(6)数据大小

empty()://利用empty() 判断list是否为空。resize(): //如果调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除,//如果需要扩展那么调用默认构造函数T()将元素加到list末端。//如果调用resize(n,val),则扩展元素要调用构造函数T(val)函数进行元素构造,其余部分相同。c.size();//返回链表c中实际元素的个数。c.max_size();//链表c可能容纳的最大元素数量。

示例:

list
 a1{1,2,3,4,5};    a1.resize(8);    list
::iterator it;    cout << "resize(n):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.resize(10, 10);    cout << "resize(n,num):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;

(7)交换操作

swap():交换两个链表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换。c1.swap(c2);      将c1和c2交换。swap(c1,c2);      同上。

示例:

list
 a1{1,2,3,4,5},a2,a3;    a2.swap(a1);    list
::iterator it;    cout << "a2.swap(a1):";    for(it = a2.begin();it!=a2.end();it++){        cout << *it << " ";    }    cout << endl;        swap(a3,a2);    cout << "swap(a3,a2):";    for(it = a3.begin();it!=a3.end();it++){        cout << *it << " ";    }    return 0;

(8)合并操作

merge()://合并两个链表并使之默认升序(也可改),l1.merge(l2,greater
()); //调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。//其实默认是升序,greater
()可以省略,另外greater
()是可以变的,也可以不按升序排列。c1.merge(c2);//合并2个有序的链表并使之有序,从新放到c1里,释放c2。c1.merge(c2,comp);//合并2个有序的链表并使之按照自定义规则排序之后从新放到c1中,释放c2。c1.splice(c1.beg,c2);// 将c2连接在c1的beg位置,释放c2c1.splice(c1.beg,c2,c2.beg);//将c2的beg位置的元素连接到c1的beg位置,并且在c2中施放掉beg位置的元素c1.splice(c1.beg,c2,c2.beg,c2.end);//c2的[beg,end)位置的元素连接到c1的beg位置并且释放c2的[beg,end)位置的元素

示例:

list
 a1{1,2,3},a2{4,5,6};    a1.merge(a2);    list
::iterator it;    cout << "a1.merge(a2):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a2.merge(a1,[](int n1,int n2){return n1>n2;});    cout << "a2.merge(a1,comp):";    for(it = a2.begin();it!=a2.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,2,3},a2{4,5,6};    a1.splice(a1.begin(), a2);    list
::iterator it;    cout << "a1.merge(a2):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;
list
 a1{1,2,3},a2{4,5,6};    a1.splice(a1.begin(), a2,++a2.begin());    list
::iterator it;    cout << "a1.merge(a2):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    return 0;
list
 a1{1,2,3},a2{4,5,6};    a1.splice(a1.begin(),a2,a2.begin(),a2.end());    list
::iterator it;    cout << "a1.merge(a2):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;    return 0;

(9)排序操作

c.sort()       将链表排序,默认升序c.sort(comp)       自定义回调函数实现自定义排序

示例:

list
 a1{1,3,2,5,4};    a1.sort();    list
::iterator it;    cout << "sort():";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;        a1.sort([](int n1,int n2){return n1>n2;});    cout << "sort(function point):";    for(it = a1.begin();it!=a1.end();it++){        cout << *it << " ";    }    cout << endl;

(10)重载运算符

operator==operator!=operator
<=operator>operator>=

示例:

list
 a1 {1,2,3,4,5},a2;a2 = a1;list
::iterator it;for(it = a2.begin();it!=a2.end();it++){    cout << *it << endl;}

转载于:https://my.oschina.net/u/2312175/blog/664294

你可能感兴趣的文章
使用Ballerina构建API网关
查看>>
dockerfile的expose
查看>>
【Mockplus教程】为什么删除多个页面的时候会有提示,如何取消提示?
查看>>
控制器中添加DB类才可以操作数据库表中的数据
查看>>
JS-面向对象
查看>>
zabbix在configure时候遇到的问题
查看>>
大公司都有哪些开源项目~~~简化版
查看>>
GIIS2017亿欧零售峰会:创业者和投资人共话产业新常态
查看>>
API网关为K8S容器应用集群提供强大的接入能力
查看>>
录取通知书玩出新花样,西工大加入AR技术
查看>>
“互联网+”农技推广让种地更简单
查看>>
Win10 Cloud会是微软的又一昏招?它会重蹈WinRT覆辙吗?
查看>>
WordPress能承载多大的数据?文章十万百万能承载吗?
查看>>
【IT背包客】第四期:CIO们的春游记
查看>>
PostgreSQL各命令行工具功能说明
查看>>
spring-编程式事务管理
查看>>
Linux系统怎么查看网卡的UUID
查看>>
NFS详细介绍与企业应用场景结合案例
查看>>
【李沐】十分钟从 PyTorch 转 MXNet
查看>>
使用Powerpoint for macos自动合并pptx文件
查看>>