博客
关于我
【C++】C++中的容器解析
阅读量:399 次
发布时间:2019-03-05

本文共 3738 字,大约阅读时间需要 12 分钟。

顺序容器与关联容器的详细解析

在C++编程中,顺序容器和关联容器是两大核心容器类型,它们各自有不同的特点和应用场景。本文将从基础到应用,全面解析这两种容器的特性、操作方法以及实际应用案例。

1. 顺序容器概述

顺序容器是最基本的C++容器类型,它以数组为基础,支持快速随机访问和元素的连续存储。常见的顺序容器包括vector、deque、list、forward_list和array等。以下是对这些容器的简要介绍:

1.1 顺序容器的种类

  • vector: 可变大小的数组,支持快速随机访问。在尾部插入或删除元素时性能较低。
  • deque: 双端队列,支持在头尾位置快速插入和删除元素,且支持快速随机访问。
  • list: 双向链表,支持在任意位置快速插入和删除元素,但不支持快速随机访问。
  • forward_list: 单向链表,操作速度与list类似,但不支持双向随机访问。
  • array: 固定大小的数组,无法插入或删除元素,仅支持随机访问。

1.2 顺序容器的操作

顺序容器支持丰富的操作方法,包括元素的插入、删除、移动和随机访问。需要注意的是,某些操作可能会导致迭代器失效,因此在操作后需要正确重新定位迭代器。

1.2.1 元素的添加与删除

  • vectorstring在尾部插入或删除元素时,可能会分配新的内存空间,导致迭代器失效。
  • deque在非首尾位置插入或删除元素时,迭代器会失效。
  • listforward_list在任何位置插入或删除元素时,迭代器仍然有效。

1.2.2 迭代器的使用

  • 迭代器是访问容器元素的重要工具,但需注意迭代器可能因容器修改操作而失效。例如:
    vector
    v = {7, 5, 16, 8};auto it = v.begin();it = v.insert(it, 200); // 迭代器被重新定位

    需要注意的是,插入或删除操作后,迭代器可能指向无效位置。

1.3 Vector容器的增长机制

为了支持快速随机访问,vector将元素存储为连续的数组。当需要扩展容量时,vector会预分配更多的内存空间,并将现有元素移动到新位置。这种策略在性能上相对较优,但插入或删除操作在尾部时会导致内存分配和移动元素。

1.3.1 容量管理

vector 提供了以下容量管理函数:

  • capacity(): 返回当前容量。
  • reserve(n): 预分配至少n个元素的内存空间。
  • shrink_to_fit(): 将容量减少到与实际大小相等。

1.3.2 示例代码

#include 
#include
int main() { std::vector
v; v.reserve(50); // 预分配50个元素的内存 v.push_back(0); // 添加元素 while (v.size() < v.capacity()) { v.push_back(0); // 使用预留空间 } v.shrink_to_fit(); // 调用shrink_to_fit return 0;}

输出结果表明,vector的实现通常将容量翻倍分配。

2. 关联容器概述

关联容器以键-值对的形式存储元素,支持快速查找和有序访问。常见的关联容器包括map、set、multimap和multiset等。

2.1 关联容器的分类

关联容器可以分为有序容器和无序容器:

  • 有序容器(map、multimap、set、multiset):元素按键值的顺序存储,支持快速查找。
  • 无序容器(unordered_map、unordered_set、unordered_multimap、unordered_multiset):元素按哈希值存储,查找速度较慢但插入和删除操作较快。

2.2 关联容器操作

关联容器提供了丰富的操作方法,包括元素的插入、删除、查找和迭代等。

2.2.1 关键字的要求

  • 有序容器要求键具有比较操作符(<)。
  • 无序容器要求键具有==运算符和哈希函数。

2.2.2 pair类型

pair类型广泛应用于关联容器中,用于存储键值对。例如:

#include 
#include
int main() { std::map
word_map; word_map.insert(std::make_pair("apple", 1)); auto it = word_map.begin(); std::cout << it->first << ":" << it->second << std::endl; return 0;}

2.3 无序容器

无序容器通过哈希函数组织元素,支持快速插入和删除操作。需要注意的是,无序容器的查找速度较慢。

2.3.1 无序容器的桶管理

无序容器将元素存储在多个桶中,每个桶包含零或多个元素。常用桶管理函数包括:

  • bucket_count(): 返回桶的数量。
  • max_bucket_count(): 返回桶的最大数量。
  • rehash(n): 重新组织桶的结构。

2.3.2 示例代码

#include 
#include
int main() { std::unordered_set
numbers; numbers.insert(10); numbers.insert(15); numbers.insert(16); auto it = numbers.find(15); std::cout << *it << std::endl; return 0;}

3. 容器适配器

除了基本容器外,C++标准库还提供了三个顺序容器适配器:stack、queue和priority_queue。这些适配器通过包装原始容器,使其行为与特定数据结构相似。

3.1 栈适配器

stack适配器可以将任何顺序容器(如vector和deque)转换为栈的行为。例如:

#include 
#include
#include
int main() { std::stack
stack; stack.push(10); stack.push(20); while (!stack.empty()) { std::cout << stack.top() << std::endl; stack.pop(); } return 0;}

3.2 队列适配器

queue适配器可以将任何顺序容器转换为队列的行为。例如:

#include 
#include
#include
int main() { std::queue
> q; q.push(std::deque
{1, 2, 3, 4}); auto front = q.front(); std::cout << front << std::endl; q.pop(); return 0;}

3.3 优先队列适配器

priority_queue适配器支持优先级队列的行为,根据指定的比较器进行元素的排序和插入。例如:

#include 
#include
#include
#include
int main() { std::priority_queue
, std::greater
> pq; pq.push(1); pq.push(8); pq.push(5); pq.push(6); pq.push(3); pq.push(4); pq.push(9); pq.push(7); pq.push(2); while (!pq.empty()) { std::cout << pq.top() << " "; pq.pop(); } return 0;}

4. 总结

顺序容器和关联容器是C++编程中的核心工具,它们在数据结构设计和算法实现中应用广泛。理解它们的特性和操作方法,对于提升编程技能至关重要。在实际开发中,选择合适的容器类型和利用容器提供的功能,可以显著提升代码的性能和可维护性。

转载地址:http://tshzz.baihongyu.com/

你可能感兴趣的文章
NetworkX系列教程(11)-graph和其他数据格式转换
查看>>
Networkx读取军械调查-ITN综合传输网络?/读取GML文件
查看>>
network小学习
查看>>
Netwox网络工具使用详解
查看>>
Net与Flex入门
查看>>
net包之IPConn
查看>>
Net操作配置文件(Web.config|App.config)通用类
查看>>
Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(7)
查看>>
New Relic——手机应用app开发达人的福利立即就到啦!
查看>>
NFinal学习笔记 02—NFinalBuild
查看>>
NFS
查看>>
NFS Server及Client配置与挂载详解
查看>>
NFS共享文件系统搭建
查看>>
nfs复习
查看>>
NFS安装配置
查看>>
NFS的安装以及windows/linux挂载linux网络文件系统NFS
查看>>
NFS的常用挂载参数
查看>>
NFS网络文件系统
查看>>
nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
查看>>
NFV商用可行新华三vBRAS方案实践验证
查看>>