c++中deque和list的基础知识

STL中deque和vector的构造函数,assign基本相同,重点介绍deque的特性,deque和vector的主要区别如下:

  • deque是双端队列的数据结构,可以在队首和队尾高效的添加和删除元素,这是相对于vector的优势。

  • deque内部采用分段连续的内存空间来存储元素,在插入元素的时候随时都可以重新增加一段新的空间并链接起来,因此虽然提供了随机访问操作,但访问速度和vector相比要慢。

  • deque并没有data函数,因为deque的元素并没有放在数组中。

  • deque不提供capacity和reserve操作。

  • deque内部的插入和删除元素要比list慢。
  • 由于deque在性能上并不是最高效的,有时候对deque元素进行排序,更高效的做法是,将deque的元素移到vector再进行排序,然后在移到回来。

  • deque为了实现整体连续的假象,导致其实现起来比较繁琐,尽量少使用它。

deque的实现原理:http://blog.csdn.net/baidu_28312631/article/details/48000123,该文叙述很清楚,可以参考。
deque的源码剖析:http://blog.csdn.net/terence1212/article/details/52326945,该文可以参考

  • deque

  • deque的初始化

  • deque的初始化,见如下代码。deque的初始化和vector完全相同
  • deque的assign函数,同样有三种方式,初始化列表,赋值若干个相同的值,任意一个序列容器的范围

    deque<int> v2;        // deque with 0 element
    deque<int> v3(20);   // deque with 20 elements whose value is 0
    deque<int> v4(20, 5);// deque with 20 elements whose value is 5
    deque<int> v5{ 20 }; // deque with 1 element whose value is 20
    deque<int> v6(v4);   // copy construct function
    deque<int> v7(v4.begin(), v4.end());//construct function
    deque<int> v8({ 1,2,3,4,5 });// construct a deque with initialize list
    deque<int> v9{ 1,2,3,4,5 };// construct a deque with initialize list
    deque<int> v10 = { 1,2,3,4,5 };// assignment construct function

  • deque的assign

  1. deque的assign有三种形式,assign

    deque<int> mydeque;
    deque<int> temp{ 1,2,4,5,6 };
    mydeque.assign(temp.begin(), temp.end());   //接受序列容器的范围
    mydeque.assign(3, 5);      //变为3个值,每个值都是5
    mydeque.assign({ 1,2,3,4,5,6 });    //赋值一个初始化列表

  • deque的添加元素

  1. deque中添加元素,除了push_back和emplace_back之外,由于是双端队列,因此可以在队首添加元素,deque中还有push_front和emplace_front等。
deque<int> myDeque;
myDeque.push_back(1);
myDeque.push_front(2);
myDeque.emplace_back(3);
myDeque.emplace_front(6);
copy(myDeque.begin(), myDeque.end(), ostream_iterator<double>(cout, " "));

  • list

  • list特点

  • list和deque的元素在内存的组织形式不同,以链表的形式保存

  • list和deque相同,也可以在尾部和头部加入元素,因此也支持push_back和push_front以及emplace_front和emplace_back

  • list可以高效的在内部插入元素而不需要移动元素,list是双向链表

  • list的insert函数和emplace与vector,deque的方式完全相同

  • list的特有的一些函数

  1. list独有的成员函数remove()可以移除和参数匹配的元素。例如如下代码:
std::list<int> numbers{2,5,2,3,6,7,8,2,9};
numbers.remove(2);// 删除元素值为2的元素
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));
  1. 成员函数remove_if()期望传入一个一元断言作为参数,一元断言接受一个和元素同类型的参数或引用,返回一个布尔值。断言返回true的元素都会被移除。断言可以是一个函数,也可以是一个lambda表达式。
std::list<int> numbers{2,5,2,3,6,7,8,2,9};
auto f = [](const int& i)->bool {return i % 2 == 0; };
numbers.remove_if(f);//删除所有偶数
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));
  1. 成员函数unique,可以移除连续重复的元素 ,只留下一个,但是该函数不能删除list中不连续的重复的元素。因此,如果需要删除重复元素,则需要排序,排序之后再删除重复元素。
    unique()函数重载形式两种,一种没有参数,有参数的版本接受一个二元断言。断言返回true的元素被认为是相等的。
//没有经过sort,直接unique
numbers.assign({ 2,5,2,4,7,7,7,8});
numbers.unique();// {2,5,2,4,7,8} 未删除重复但不连续的元素
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));

// sort 之后unique
numbers.assign({ 2,5,2,4,7,7,7,8 });
numbers.sort();// 2,2,4,5,7,7,7,8
numbers.unique();// 2,4,5,7,8
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));


//unique 的重载形式
numbers.assign({ 2,5,2,4,7,7,7,8 });
numbers.sort();// 2 2 4 5 7 7 7 8
auto f1 = [](const int& a, const int& b)->bool {return a % 2 == b % 2; };
numbers.unique(f1);// 2 5 8
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, " "));
  1. sort()函数有两个版本:无参数的sort()将所有元素升序排列,有参数版本的sort()函数接受一个函数对象或者lambda函数,用来表明排序依据。
// 使用断言
numbers.assign({ 2,5,2,4,7,7,7,8 });
numbers.sort(greater<>());// 2 2 4 5 7 7 7 8
// 使用lambda函数
numbers.assign({ 2,5,2,4,7,7,7,8 });
auto f3 = [](const int&a, const int& b)->bool{return a>b;};
numbers.sort(f3);// 2 2 4 5 7 7 7 8

上述例子中使用了functional中的模板greater<T>断言,这里可以使用gerater<int>的形式,也可以使用greater<>的形式,后者是简洁版本的函数对象,可以接受任何类型的参数,使用完美转发(perfect forwarding)可以避免参数拷贝,被比较的参数会被移动而不是复制到函数中。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值