--------------------------------------------------------------------------------------------------------------------------------
因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,具体可以遵循下面的原则:
1. 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2. 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3. 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
--------------------------------------------------------------------------------------------------------------------------------
对于一个双向链表来说主要包括3个:前向指针、有效数据、后向指针
链表相对于vector向量来说的优点在于:
(a)动态的分配内存;
(b)支持任意位置的插入和删除;
缺点:
(a)、不能随机访问;
(b)、不支持[]方式和at();
(c)、没有提供容量、空间重新分配等函数,占用的内存会多于vector(非有效数据占用的内存空间)
1、初始化list对象的方式
list<int> L0; //空链表
list<int> L1(3); //建一个含三个默认值是0的元素的链表
list<int> L2(5,2); //建一个含五个元素的链表,值都是2
list<int> L3(L2); //L3是L2的副本
list<int> L4(L1.begin(),L1.end()); //c5含c1一个区域的元素[begin, end]。
(2)赋值
插入:头push_front()、尾push_back()、
获取:头pop_front()、尾pop_back()
(3)、容量
size()、resize()、max_size()
(4)、迭代器相关
begin()、end()、rbegin()、rend()、front()、back()、
注解:
begin():返回list容器的第一个元素的地址
end():返回list容器的最后一个元素之后的地址
rbegin():返回逆向链表的第一个元素的地址(也就是最后一个元素的地址)
rend():返回逆向链表的最后一个元素之后的地址(也就是第一个元素再往前的位置)
front():返回链表中第一个数据值
back():返回链表中最后一个数据值
empty():判断链表是否为空
size():返回链表容器的元素个数
clear():清除容器中所有元素
insert(pos,num):将数据num插入到pos位置处(pos是一个地址)
insert(pos,n,num):在pos位置处插入n个元素num
erase(pos):删除pos位置处的元素
push_back(num):在链表尾部插入数据num
pop_back():删除链表尾部的元素
push_front(num):在链表头部插入数据num
pop_front():删除链表头部的元素
sort():将链表排序,默认升序
assign():具体和vector中的操作类似,也是有两种情况,第一种是:l1.assign(n,val)将 l1中元素变为n个T(val)。第二种情况是:l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1。
swap():交换两个链表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换。
merge():合并两个链表并使之默认升序(也可改),l1.merge(l2,greater<int>()); 调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。其实默认是升序,greater<int>()可以省略,另外greater<int>()是可以变的,也可以不按升序排列。
insert():在指定位置插入一个或多个元素(三个重载):
l1.insert(l1.begin(),100); 在l1的开始位置插入100。
l1.insert(l1.begin(),2,200); 在l1的开始位置插入2个100。
l1.insert(l1.begin(),l2.begin(),l2.end());在l1的开始位置插入l2的从开始到结束的所有位置的元素。
erase():删除一个元素或一个区域的元素(两个重载)
l1.erase(l1.begin()); 将l1的第一个元素删除。
l1.erase(l1.begin(),l1.end()); 将l1的从begin()到end()之间的元素删除。
练习代码:
//防止编译时发出太多警告
#pragma warning(disable:4786)
#include <iostream>
#include <list>
#include <algorithm>
#include <functional>
using namespace std;
//模板函数
template <class T> void print(const T& t) {
cout << t <<" ";
}
//模板函数
template <class T> void print_vt(list<T>& vt) {
list<T>::iterator ivt;
for (ivt = vt.begin(); ivt!=vt.end(); ivt++)
{
cout << *ivt << " ";
};
}
//格式化输出
void print_d(double &d){
cout.width(5);
cout.precision(1);
cout << fixed << d << ",";
}
void main() {
//初始化
list<int> l1;
list<double> l2(6);
list<double> l3(6, 3);
list<double> l4(l2);
list<double> l5(l3.begin(), l3.end());
//初始化l1
for (int i = 0; i < 8; i++)
{
double temp = i * 6 + 1;
l1.push_front(temp); //前端插入初始化
}
//初始化l2
for(int i = 0; i<=5; i++)
{
double temp = i * 10.5 + 1;
l2.push_front(temp);
}
list<int>::iterator it1;
cout << "L1:";
for (it1 = l1.begin(); it1 != l1.end();it1++)
{
int temp = *it1;
print(temp); //模板函数输出
}
cout << endl;
cout <<"l1.size:"<< l1.size() << endl;
cout << "L2:";
list<double>::iterator it2;
for (it2 = l2.begin(); it2!=l2.end(); it2++)
{
cout << *it2 << " ";
}
cout << endl;
//list元素的存取和访问:不提供at()和操作符operator[]
cout << "第三个元素:" << *(++(++(++l2.begin()))) << endl;
cout << "L3:";
//元素重置assign()
l3.assign(l2.begin(),l2.end());
for_each(l3.begin(),l3.end(),print_d);
cout << endl;
//重新设置l4的大小
cout << "L4:";
l4.resize(3);
l4.push_front(2.5);
l4.push_back(4.4);
l4.push_back(5.3);
//判断为空函数
if(l4.empty())
{
cout << "l4空" << endl;
}
else {
//for_each函数
for_each(l4.begin(), l4.end(), print_d);
cout << endl;
bool empty = l4.empty();
cout << "第一个元素"<<l4.front() << " " << "empty:"<<empty;
}
//交换swap(a,b)
swap(l2,l4);
cout << endl;
cout << "l2:";
print_vt(l2);
cout << endl;
cout << "l3:";
print_vt(l3);
cout << endl;
//插入insert()
l3.insert(++l3.begin(), 3.99);
print_vt(l3);
//删除erase()、clear()、remove()、remove_if()、pop_front()、pop_back()
l1.pop_front();
l1.pop_back();
print_vt(l1);
cout << endl;
l1.erase(++l1.begin());
print_vt(l1);
cout << endl;
l1.clear();
print_vt(l1);
cout << endl;
//删除具体的value元素;
l2.remove(4);
print_vt(l1);
cout << endl;
//bin2nd(操作类型对象,值)
l2.remove_if(bind2nd(not_equal_to<int>(),1));
print_vt(l1);
cout << endl;
//operator操作符==、<、!=、<=、>、>=【主要用来比较两个相同的list】
//merge():升序排列
l2.merge(l3);
cout << "l2:";
print_vt(l2);
cout << endl;
cout << "L2降序排列:";
l2.sort(greater<double>());
print_vt(l2);
cout << endl;
//slice()
l4.splice(l4.end(),l3,(++l2.begin()));
print_vt(l4);
cout << endl;
//移除【相邻的】重复元素
l4.sort();
l4.unique();
print_vt(l4);
cout << endl;
not_equal_to <double> Pred;
l4.sort();
l4.unique(Pred); //仅仅保留和第一个元素相等的元素;参数仅仅提供谓词
print_vt(l4);
cout << endl;
//调换顺序
l4.reverse();
print_vt(l4);
cout << endl;
system("pause");
}