STL list
类似于双向链表
-
最大的特点:插入或删除元素后,指向 list 中其他元素的迭代器仍有效
-
插入、删除元素的时间固定
-
不能像vector随机访问
list实例化
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
//实例化list,需要指定list的存储数据类型
list <int> listIntegers;
//确定长度的list实例化
list <int> listWithTenElements (10);
//长度为10,每个元素值为99
list <int> listWith10IntegersEach99(10, 99);
//复制list的方式来初始化一个list对象
list <int> listCopy (listWith10IntegersEach99);
//用其他容器的值(这里是vector)来初始化list
vector <int> vecIntegers (10);
list <int> listContainsCopyOfAnother(vecIntegers.cbegin(), vecIntegers.cend());
system("pause");
return 0;
}
头、尾、中间插入元素
/*
成员函数 list::insert()有 3 种版本
• iterator insert(iterator pos, const T& x)
在这里,insert 函数接受的第 1 个参数是插入位置,第 2 个参数是要插入的值。该函数返回一
个迭代器,它指向刚插入到 list 中的元素。
• void insert(iterator pos, size_type n, const T& x)
该函数的第 1 个参数是插入位置,最后一个参数是要插入的值,而第 2 个参数是要插入的元素
个数。
• template <class InputIterator>
void insert(iterator pos, InputIterator f, InputIterator l)
除一个位置参数外,它还接受两个输入迭代器,指定要将集合中相应范围内的元素插入到 list 中。
注意,输入类型 InputIterator 是一种模板参数化类型,因此可指定任何集合(数组、vector 或另一个 list)的边界。
*/
#include <iostream>
#include <list>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
//1. 从头或尾插入
list <int> listIntegers;
listIntegers.push_back(2);
listIntegers.push_back(3);
listIntegers.push_front(1);
listIntegers.push_front(0);
DisplayContents(listIntegers); // 0 1 2 3
//2. 从中间插入
list <int> listIntegers1;
listIntegers1.insert(listIntegers1.begin(), 2);
listIntegers1.insert(listIntegers1.begin(), 1);
listIntegers1.insert(listIntegers1.end(), 3);
DisplayContents(listIntegers1); // 1 2 3
list <int> listIntegers2;
listIntegers2.insert(listIntegers2.begin(), 4, 0);
cout << "The contents of list 2 after inserting ";
cout << listIntegers2.size() << " elements of a value:" << endl;
DisplayContents(listIntegers2); // 0 0 0 0
list <int> listIntegers3;
listIntegers3.insert(listIntegers3.begin(),
listIntegers1.begin(), listIntegers1.end());
cout << "The contents of list3 after inserting the contents of ";
cout << "list 1 at the beginning: " << endl;
DisplayContents(listIntegers3); // 1 2 3
listIntegers3.insert(listIntegers3.end(),
listIntegers2.begin(), listIntegers2.end());
cout << "The contents of list3 after inserting the contents of ";
cout << "list 2 at end:" << endl;
DisplayContents(listIntegers3); // 1 2 3 0 0 0 0
return 0;
}
删除
#include <iostream>
#include <list>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
list <int> listInteger{
4, 3, 5, -1, 2017};
auto val2 = listInteger.insert(listInteger.begin(), 2);
cout << "Initial contents: ";
DisplayContents(listInteger); // 2 4 3 5 -1 2017
// 接受一个迭代器参数并删除迭代器指向的元素
cout << "After erasing element '"<< *val2 << "':" << endl;
listInteger.erase(val2);
DisplayContents(listInteger); // 4 3 5 -1 2017
// 接受两个迭代器参数并删除指定范围内的所有元素
listInteger.erase(listInteger.begin(), listInteger.end());
cout << "Number of elements after erasing range: ";
cout << listInteger.size() << endl; // 0
system("pause");
return 0;
}
用于插入一个元素时,insert() 返回一个迭代器,该迭代器指向新插入的元素
用 size() 确定大小,同样适用于 std::list
反转、排序
#include <iostream>
#include <list>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
list <int> listIntegers{
0, 1, 2, 3, 4, 5};
cout << "Initial contents of the list:" << endl;
DisplayContents(listIntegers);
cout << "After using reverse():" << endl;
listIntegers.reverse();
DisplayContents(listIntegers);
system("pause");
return 0;
}
#include <iostream>
#include <list>
using namespace std;
// 二元谓词,帮助sort判断一个元素是否比另一个元素小
bool SortPredicate_Descending (const int& lsh, const int& rsh)
{
return (lsh > rsh);
}
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
list <int> integers {
0, -1, 2011, 444, -5};
cout << "Initial contents of the list are - " << endl;
DisplayContents(integers); // 0 -1 2011 444 -5
integers.sort();
cout << "Order of elements after sort():" << endl;
DisplayContents(integers); // -5 -1 0 444 2011
integers.sort(SortPredicate_Descending);
cout << "Order of elements after sort() with a predicate:" << endl;
DisplayContents(integers); // 2011 444 0 -1 -5
system("pause");
return 0;
}
不带参数的 sort() 方法,使用的 < 比较证书,默认按照升序排序
5-8行的二元谓词重新定了 < : lsh 的值大于 rsh的值,说明 lsh 比 rsh ”小“
包含对象的list进行排序及删除
#include <iostream>
#include <list>
#include <string>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << endl;
}
cout << endl;
}
struct ContactItem
{
string strContactsName;
string strPhoneNumber;
string strDisplayRepresentation;
ContactItem (const string &strName, const string &strNumber)
{
strContactsName = strName;
strPhoneNumber = strNumber;
strDisplayRepresentation = (strContactsName + ": " + strPhoneNumber);
}
bool operator == (const ContactItem& itemToCompare) const
{
return (itemToCompare.strContactsName == this->strContactsName);
}
bool operator < (const ContactItem& itemToCompare) const
{
return (this->strContactsName < itemToCompare.strContactsName);
}
operator const char*() const
{
return strDisplayRepresentation.c_str();
}
};
bool SortOnPhoneNumber (const ContactItem& item1, const ContactItem& item2)
{
return item1.strPhoneNumber < item2.strPhoneNumber;
}
int main()
{
list <ContactItem> Contacts{
ContactItem("Jack Welsch", "+1 7889879879"),
ContactItem("Bill Gates", "+1 97789787998"),
ContactItem("Angi Merkel", "+49 234565466"),
ContactItem("Vlad Putin", "+7 66454564797"),
ContactItem("Ben Affleck", "+1 745641314"),
ContactItem("Dan Craig", "+44 123641976")
};
cout << "List in initial order: " << endl;
DisplayContents(Contacts);
Contacts.sort();
cout << "Sorting in alphabetical order via operator<:" << endl;
DisplayContents(Contacts);
Contacts.sort(SortOnPhoneNumber);
cout << "Sorting in order of phone numbers via predicate:" << endl;
DisplayContents(Contacts);
cout << "After erasing Putin from the list:" << endl;
Contacts.remove(ContactItem("Vlad Putin", ""));
DisplayContents(Contacts);
return 0;
}
STL forward_list
forward_list 只能沿着一个方向移动迭代器,只能通过 push_front() 从头部插入元素。当然也可以用 insert() 插入元素
#include <iostream>
#include <forward_list>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin()
; iElement != Input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
forward_list <int> flistIntegers;
flistIntegers.push_front(0);
flistIntegers.push_front(2);
flistIntegers.push_front(2);
flistIntegers.push_front(4);
flistIntegers.push_front(3);
flistIntegers.push_front(1);
cout << "Contents of forward_list: " << endl;
DisplayContents(flistIntegers);
flistIntegers.remove(2);
cout << "Contents after removing value 2:" << endl;
DisplayContents(flistIntegers);
flistIntegers.sort();
cout << "Contents after sorting:" << endl;
DisplayContents(flistIntegers);
system("pause");
return 0;
}