List链表
- 基本概念
- 构造函数
- 赋值和交换
- 大小操作
- 插入和删除
- 数据存取
- 反转和排序
基本概念
将数据进行链式存储
链表list是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的,链表是由一系列结点组成,结点的组成一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域STL中的链表是一个双向循环链表。更深层次的理解可以看看数据结构中的链表。
优点:可以对任意的位置进行快速插入或删除元素。
缺点:容器遍历速度,没有数组快,占用的空间比数组大。
数组的优缺点和链表相反。
在链表中在任意位置插入和删除元素不会造成原有list迭代器的失效,这个在vector中不成立。
总结:STL中list和vector是两个最常被使用的容器,各有优缺点。
构造函数
1、list lst;默认构造函数形式,采用模板类实现
2、list(beg,end);构造函数将[beg,end]区间中的元素拷贝给本身
3、list(n,elem);构造函数将n个elem拷贝给本身
4、list(const list &lst);拷贝构造函数
void test1() {
list<int> l;
l.push_back(123);
l.push_back(50);
l.push_back(34);
l.push_back(111);
p(l);
list<int>l2(l.begin(), l.end());
p(l2);
list<int>l3(5, 50);
p(l3);
list<int>l4(l3);
p(l4);
}
赋值和交换
1、assign(beg,end);
将[beg,end]区间中的元素拷贝给本身
2、assign(n,elem);
将n个elem赋值给本身
3、list& operator=(const list &lst);
重载等号操作符
4、swap(lst);
将lst和本身的元素互换
void test1() {
...
list<int>l2;
l2.assign(l.begin(), l.end());
list<int>l3;
l3.assign(5, 50);
list<int>l4;
l4 = l3;
l3.swap(l2);
...
}
大小操作
1、empty();
判断容器是否为空
2、size();
返回容器中元素的个数
3、resize(num);
重新指定容器的长度为num,若容器变长,则以默认值0填充新位置;若容器变短,则末尾超出容器长度的元素被删除
4、resize(num,elem);
重新指定容器的长度为num,若容器变长,则以elem值填充新位置;若容器变短,则末尾超出容器长度的元素被删除
if (!l.empty()) {
cout << "大小" << l.size()<<endl;
}
l.resize(6,10);
cout << "大小" << l.size() << endl;
插入和删除
1、push_back(ele);
尾部插入元素ele
2、push_front();
在头部插入一个数据
4、pop_back();
删除最后一个元素
5、pop_front();
删除第一个元素
6、insert(pos,ele)
;迭代器指向位置pos插入元素ele的拷贝,返回新数据的位置
7、insert( pos,n,ele);
迭代器指向位置pos插入n个元素ele,无返回值
8、insert(pos,beg,end);
在pos位置插入[beg,end)区间的数据,无返回值
9、erase(pos);
删除pos位置的元素,返回下一个数据的位置
10、erase(beg,end);
删除迭代器从start到end之间的元素,返回下一个数据的位置
11、clear();
删除容器中的所有元素
12、remove(elem);
删除容器中所有与elem值相匹配的元素
void test1() {
list<int> l;
l.push_back(123);
l.push_back(50);
p(l);
l.erase(l.begin(), l.end());
l.push_front(34);
l.push_front(111);
p(l);
l.pop_back();
l.pop_front();
p(l);
l.insert(l.begin(), 99);
l.insert(l.begin()++, 3, 999);
l.insert(l.end(), l.begin(), l.end());
p(l);
l.erase(l.begin());
p(l);
l.remove(999);
p(l);
l.clear();
p(l);
}
数据存取
不可以使用[]和at访问,因为list链表不是连续性空间存储数据,迭代器不支持随机访问。
1、front();
返回第一个元素
2、back();
返回最后一个元素
void test1() {
...
cout << "第一个元素" << l.front() << endl;
cout << "最后一个元素" << l.back() << endl;
}
反转和排序
1、reverse();
反转
2、sort();
排序
void test1() {
list<int> l;
l.push_back(123);
l.push_back(50);
l.push_front(34);
l.push_front(111);
//所有不支持随机访问迭代器的容器,不可以用标准算法
//不支持随机访问迭代器的容器会内部会提供对应的一些算法
sort(l.begin(), l.end());//运行时会报错
//不属于全局函数,相当于成员函数,默认从小到大
l.sort();
p(l);
l.sort(myCompare);
p(l);
l.reverse();
p(l);
}
自定义类排序
class S {
public:
int age;
string name;
int h;
S(string _n, int _a,int _h) {
name = _n;
age = _a;
h = _h;
}
};
//降序排序
bool CompareS(S v1,S v2) {
if (v1.age == v2.age) {
return v1.h > v2.h;
}
return v1.age < v2.age;
}
void test1() {
list<S> l;
S s1("Tom", 18, 187);
S s2("Lisa", 20, 165);
S s3("LuJy", 34, 190);
S s4("Tony", 21, 167);
S s5("Ala", 20, 168);
l.push_back(s1);
l.push_back(s2);
l.push_back(s3);
l.push_back(s4);
l.push_back(s5);
for (list<S>::iterator it = l.begin();it != l.end();it++) {
cout << "姓名:" << (*it).name << "\t年龄:" << (*it).age << "\t身高:" << (*it).h << endl;
}
cout << "-----------------------------------------" << endl;
l.sort(CompareS);
for (list<S>::iterator it = l.begin();it != l.end();it++) {
cout << "姓名:" << (*it).name << "\t年龄:" << (*it).age << "\t身高:" << (*it).h << endl;
}
}