list的本质是带头双向循环链表,对于带头双向循环链表我们可是比较熟悉的了。本文只对list的一些常用接口进行说明,对于其他一些接口可自行查看文档。


void Test()
{list lt;//无参构造list lt1(5, 1);//n个val构造list lt2(lt1);//拷贝构造string s("hello world");list lt3(s.begin(), s.end());//迭代器区间构造
}

//正向迭代器
int main()
{list lt(5, 10);list::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;return 0;
}

//反向迭代器
int main()
{list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;return 0;
}

1.头插头删
push_front和pop_front
int main()
{list lt;lt.push_front(10);lt.push_front(20);lt.push_front(30);lt.push_front(40);for (auto e : lt){cout << e << " ";}cout << endl;lt.pop_front();lt.pop_front();for (auto e : lt){cout << e << " ";}return 0;
}

2.尾插尾删
push_back和pop_back
int main()
{list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;lt.pop_back();lt.pop_back();for (auto e : lt){cout << e << " ";}cout << endl;return 0;
}

3.查找和插入
find和insert
find和insert可以相互配合使用。find是算法库里面的,在添加头文件#include
对于list的插入insert:

1.通过find找到位置插入
2.找到位置后插入n个val的值
3.找到位置后插入迭代器的区间
int main()
{list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);//1.插入一个值auto pos = find(lt.begin(), lt.end(), 3);if (pos != lt.end()){//对于链表的insert,迭代器不会失效lt.insert(pos, 30);}for (auto e : lt){cout << e << " ";}cout << endl;cout << *pos << endl;//2.插入n个val的值pos = find(lt.begin(), lt.end(), 3);if (pos != lt.end()){lt.insert(pos, 4, 100);}for (auto e : lt){cout << e << " ";}cout << endl;//3.插入迭代器区间list tmp(3, 8);pos = find(lt.begin(), lt.end(), 100);if (pos != lt.end()){lt.insert(pos, tmp.begin(), tmp.end());}for (auto e : lt){cout << e << " ";}cout << endl;return 0;
}

注意:对于list的insert的pos位置不会失效,在这个地方,只是在pos位置前增加节点,改变链接,pos位置并不会变成野指针。
4.删除
erase

int main()
{list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(5);auto pos = find(lt.begin(), lt.end(), 3);if (pos != lt.end()){lt.erase(pos);}for (auto e : lt){cout << e << " ";}cout << endl;pos = find(lt.begin(), lt.end(), 4);if (pos != lt.end()){lt.erase(pos, lt.end());}for (auto e : lt){cout << e << " ";}cout << endl;
}

注意:对于list的erase的pos位置是会失效的,删除之后,如果直接进行访问会直接报错,此时的pos已经是野指针了。
排序和去重
1.sort和unique
对于sort:算法库里面已经有一个sort了,而对于list自己也提供了一个sort:
算法库里的sort对于list并不适用,算法库里的sort对于物理空间是连续的,只有vector和string能够使用,而对于list来说,物理空间并不是连续的,并不适用,所以list自己提供了一个sort进行排序,此外,链表的排序是归并排序。
int main()
{list lt;lt.push_back(10);lt.push_back(2);lt.push_back(5);lt.push_back(6);lt.push_back(4);lt.push_back(4);lt.push_back(6);lt.push_back(4);lt.push_back(0);for (auto e : lt){cout << e << " ";}cout << endl;lt.sort();for (auto e : lt){cout << e << " ";}cout << endl;return 0;
}

对于unique:用来删除链表中连续的重复元素,但是注意:一定是要先排完序在进行删除,如果没有进行排序:而直接进行去重的话,会导致去重去不完全
int main()
{list lt;lt.push_back(10);lt.push_back(2);lt.push_back(5);lt.push_back(6);lt.push_back(4);lt.push_back(4);lt.push_back(6);lt.push_back(4);lt.push_back(0);for (auto e : lt){cout << e << " ";}cout << endl;lt.sort();lt.unique();for (auto e : lt){cout << e << " ";}cout << endl;return 0;
}

2.splice和remove
slice进行转移:

int main()
{//转移到某个位置list lt1(5,10);list lt2(4,7);lt1.splice(lt1.begin(), lt2);for (auto e : lt1){cout << e << " ";}cout << endl;//从某个位置转移list lt3(4,10);list lt4(4, 5);lt3.splice(lt3.begin(), lt4, lt4.begin());for (auto e : lt3){cout << e << " ";}cout << endl;//迭代器区间转移listlt5(3,10);listlt6(3,20);lt5.splice(lt5.begin(), lt6, lt6.begin(), lt6.end());for (auto e : lt5){cout << e << " ";}cout << endl;return 0;
}

remove可以直接删除list中指定的数据:
int main()
{list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(5);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.remove(5);for (auto e : lt){cout << e << " ";}cout << endl;return 0;
}

3.resize

感觉resize放在list这里并不太常用把,简单测试一下代码:
int main()
{list lt;lt.resize(5, 1);for (auto e : lt){cout << e << " ";}cout << endl;list lt2;lt2.push_back(1);lt2.push_back(2);lt2.push_back(3);lt2.push_back(4);lt2.push_back(5);lt2.push_back(6);lt2.resize(4);for (auto e : lt2){cout << e << " ";}cout << endl;return 0;
}