前言:
现在你们对“c升序排列函数”都比较关怀,朋友们都想要了解一些“c升序排列函数”的相关资讯。那么小编在网上收集了一些对于“c升序排列函数””的相关知识,希望大家能喜欢,姐妹们一起来学习一下吧!顺序容器就是数据结构里的线性表,一共有 5 种:array、vector、deque、list、forward_list
如果按照存储的方式又可以分为链式存储(list 和 forward_list)和连续地址存储(array、vector 和 deque)
连续地址存储
链式存储
优点
查找效率高
插入删除效率高
缺点
插入删除效率低
查找效率低,存储成本略高
对于array和vector在内存中的数据存放与C语言完全兼容,所以对于数据的操作速度很快。这两种容器的区别在于array是不能扩容的,而vector可以动态的扩容。
#include <iostream>#include <vector>#include <array>#include <algorithm>int main(){ std::array<int, 10> arr; std::vector<int> v; std::for_each( cbegin(arr), cend(arr), [&v](const auto& i) { v.emplace_back(i); }); std::cout << arr.size() << std::endl; // 10 std::cout << v.size() << std::endl; // 10 return 0;}
deque与vector的最大的区别是deque可以两头进行插入。删除的操作,vector只能在尾部进行插入和删除的操作。
#include <iostream>#include <deque>int main(){ std::deque<int> q; q.emplace_back(1); q.emplace_front(2); for(auto i : q) { std::cout << i << " "; // 2 1 } return 0;}
list 是双向链表,可以向前或者向后遍历,而 forward_list则是单向链表,只能向前遍历,查找效率会比list低。
#include <iostream>#include <list>#include <forward_list>int main(){ std::list<int> l; l.emplace_back(1); l.emplace_front(2); l.emplace_back(3); for(auto i : l) { std::cout << i << " "; // 2 1 3 } std::cout << std::endl; std::forward_list<int> fl; fl.emplace_front(2); fl.emplace_front(1); for(auto i : fl) { std::cout << i << " "; // 1 2 } std::cout << std::endl; return 0;}
虽然vector、deque、list和forward_list都可以进行动态的扩容,但是它们的机制是完全不同的。我们先看看vector是怎么扩容的:
#include <iostream>#include <vector>struct Point{ int m_a; int m_b; Point (int a, int b) : m_a(a), m_b(b) { std::cout << "构造函数" << std::endl; } Point (const Point& p) : m_a(p.m_a), m_b(p.m_b) { std::cout << "拷贝构造" << std::endl; } Point (Point &&p) : m_a(p.m_a), m_b(p.m_b) { std::cout << "移动构造" << std::endl; }};int main(){ std::vector<Point> v; for (int i = 1; i <= 5; i++) { std::cout << "*********" << i << "***********" << std::endl; v.emplace_back(i, i + 1); std::cout << "v.size = " << v.size() << std::endl; } return 0;}
输出结果如下:
大家有没有发现,有时候会莫名其妙的调用拷贝构造函数,这是为什么呢?这是因为当 vector 的容量不够的时候,它会去寻找一块两倍大小的新内存,然后把旧元素拷贝或者移动过去,最后把新数据插入进去。这个问题之前我在工作中遇到过,所以影响特别深。我记得当时的业务中需要在vector容器中进行大量的数据插入,等数据达到一定量级的时候,接口返回时间越来越长。最后找到是这个原因导致,通过reserve接口进行所需容器的空间预估,可以减少动态扩容的调用拷贝构造的次数,从而提高程序性能。
而deque、list和forward_list相对比较简单,插入一个数据,扩容一个数据的大小。但是如果短时间有大量的数据插入,这时候一次性分配足够大的空间的vector的优势就比较明显了。所以实际开发中vector出现的记录很高。
标签: #c升序排列函数