C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用

摘要:
本文主要通过对C++标准模板库STL中实现的数据结构的研究和使用,加深对数据结构的理解,即将数据结构的理论分析与具体应用实现联系起来。本文是一系列总结中的第一篇,主要集中于线性表中序列表STL矢量的分析和总结。C++标准模板库中序列表的实现对应于C++STL标准模板库的模板向量的实现:模板<classType,classAllocator=allocater<Type>>classvector</span˃其中,Type是存储在vector中的数据类型,使用时应包含头文件<vector>和命名空间std。
摘要

本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解,即联系数据结构的理论分析和具体的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动态数组)STL vector进行分析和总结


引言

由于前段时间对台大的机器学习基石和技法课程进行了学习,发现在具体的实现中常常涉及到各种类型的数据结构,比如线性表、二叉树、图等,在使用这些数据结构时感到有些吃力,主要是对一些基本的数据结构理解的不够,所以趁着暑假假期,最近一段时间总会抽空复习一下数据结构,参考的教材是王立柱编著的《C/C++与数据结构》,在具体的应用中采用的是C++标准模板库STL中对应实现的数据结构,主要参考的是MSDN文档


正文

基本数据结构

数据结构中最简单的一个实现就是线性表中的顺序表,其数据结构如图所示:

C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用第1张

数据结构上的实现为:

typedef struct

{

  DataType *m_pData;

    int m_nMax,m_nSize;

}SeqList;

typedef int DataType;

从结构上看,顺序表就是一个动态数组,需要有一个容量为m_nMax和一个用来记录表中已经有多少数据的m_nSize。而动态数组的容量在运行过程中是可以扩充和缩减的。因此也就比单纯的数组具有更加灵活的结构!

顺序表在C++的标准模板库中的实现

对应在C++的STL标准模板库中的实现是模板 vector:

<span style="font-size:18px;">template <
   class Type, 
   class Allocator = allocator<Type> 
>
class vector</span>

其中,Type是vector中存储的数据类型,使用时要包括头文件<vector>和命名空间std。

vector模板类中使用的数据类型

首先先认识一下vector模板类中最常使用的数据类型:

iterator 迭代器

用来提供对vector中元素随机访问的一个数据类型,可读可修改。

const_iterator 常量迭代器

用来提供对vector中元素随机访问,只能读一个const不变的元素。

具体使用如下:

<span style="font-size:18px;">// vector_begin.cpp
// compile with: /EHsc
#include <vector>
#include <iostream>

int main()
{
    using namespace std;
    vector<int> c1;
    vector<int>::iterator c1_Iter;
    vector<int>::const_iterator c1_cIter;

    c1.push_back(1);
    c1.push_back(2);

    cout << "The vector c1 contains elements:";
    c1_Iter = c1.begin();
    for (; c1_Iter != c1.end(); c1_Iter++)
    {
        cout << " " << *c1_Iter;
    }
    cout << endl;

    cout << "The vector c1 now contains elements:";
    c1_Iter = c1.begin();
    *c1_Iter = 20;
    for (; c1_Iter != c1.end(); c1_Iter++)
    {
        cout << " " << *c1_Iter;
    }
    cout << endl;

    // The following line would be an error because iterator is const
    // *c1_cIter = 200;
}</span>

vector模板类的成员函数

assign 

擦除改vector,并复制具体的元素到这个矢量中。

<span style="font-size:18px;">// vector_assign.cpp
// compile with: /EHsc
#include <vector>
#include <iostream>

int main( )
{
   using namespace std;
   vector<int> v1, v2, v3;
   vector<int>::iterator iter;

   v1.push_back(10);
   v1.push_back(20);
   v1.push_back(30);
   v1.push_back(40);
   v1.push_back(50);

   cout << "v1 = " ;
   for (iter = v1.begin(); iter != v1.end(); iter++)
      cout << *iter << " ";
   cout << endl;

   v2.assign(v1.begin(), v1.end());
   cout << "v2 = ";
   for (iter = v2.begin(); iter != v2.end(); iter++)
      cout << *iter << " ";
   cout << endl;

   v3.assign(7, 4) ;
   cout << "v3 = ";
   for (iter = v3.begin(); iter != v3.end(); iter++)
      cout << *iter << " ";
   cout << endl;
}</span>
输出为:

v1 = 10 20 30 40 50 
v2 = 10 20 30 40 50 
v3 = 4 4 4 4 4 4 4

front和back 

分别返回vector中第一个和最后一个元素的引用。使用案例如下:

<span style="font-size:18px;">// vector_back.cpp
// compile with: /EHsc
#include <vector>
#include <iostream>

int main() {
   using namespace std;   
   vector <int> v1;
   
   v1.push_back( 10 );
   v1.push_back( 11 );

   int& i = v1.back( );
   const int& ii = v1.front( );

   cout << "The last integer of v1 is " << i << endl;
   i--;
   cout << "The next-to-last integer of v1 is "<< ii << endl;
}</span>
输出为:

The last integer of v1 is 11
The next-to-last integer of v1 is 10

其他操作函数 

swap在两个vector之间交换元素;size获取表中数据的个数;resize重新调整vector的数据个数;reserve保留一个最小长度的存储空间;push_back(size加1)和pop_back(size-1)实现的是在vector尾部插入和删除数据;insert在特定的位点插入一个或许多元素;erase擦掉一个或者一段范围内的元素。clear是擦除整个vector中的元素(size=0)。

重载运算符 

[]使得vector可以像数组一样访问;=使得vector可以直接用右边的矢量去替换,而不用对左边进行存储空间的初始化等操作。

其他注意事项和使用经验 

有了以上的说明,我们在使用时,还需要知道一下的几种初始化,vector嵌套的定义和使用小技巧等:

vector<vector<float>> test = vector<vector<float>>(5,vector<float>(6, 0.0f));

这样就初始化了一个二维的float 型 vector,现在test里面装有5个float型的vector<float>,而这个float型的vector<float>又被初始化为6个0.0f的一维vector。

在C++中常常使用引用&作为函数的形参,比如vectorMutiply(vector<float>& x1, vector<float>& x2);

定义完vector,没有进行初始化操作,直接采用push_back()的方法可以进行插入,vector的最大存储空间capacity会动态的增加,用户不需要进行手动的调整。另外,可以直接利用等号=进行copy赋值操作,它的空间会系统自动分配。





免责声明:文章转载自《C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇猜算式js 获取图片url的Blob值并预览下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用C++ 实现的 websocket 客户端 (基于easywsclient)

直接上代码 easywsclient.hpp #ifndef EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD #define EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD // This code comes from: // https://github.co...

C++ 的erase和remove remove_if删除元素

1. erase   很多时候,我在删除vector元素的时候使用的是遍历指针,符合条件时使用erase删除, 可是这样的使用办法会有个问题,在vec.erase(iter)后,需要使用erase的返回值,并且这个返回值是等价iter++,也就是iter的下一个元素, 否则的话,iter将会是个无效指针 vector<int> vec_...

C++ 迭代器失效问题

今天同学华为面试被问到vector有什么问题了,我一拍脑门,vector有什么问题?? 原来是迭代器失效问题。先看看vector中: void test_vector_erase(){ vector<int> v = {1,2,3,4,5}; for(auto it = v.begin(); it != v.end(); it+...

netflix vector 系统性能监控安装使用

说明本次安装使用docker 1. vector 安装 docker run -d --name vector -p 80:80 netflixoss/vector:latest 2. 依赖的pcp 安装 yum install -y pcp-webapi pcp 3. 服务启动 a. vector docker 默认已经启动 b. pcp syste...

Vector的用法

vector容器是笔试时最经常用到的容器,它实际是一个类模板,它所具有一些成员函数我们必须熟练使用,这样才会加快编程速度。 首先加头文件并定义: #include<vector> vector<int>vec; 1、获取vector里的元素个数 int len =vec.size(); 2、向vector添加元素 int temp;...

Java生鲜电商平台-商品的spu和sku数据结构设计与架构

Java生鲜电商平台-商品的spu和sku数据结构设计与架构 1. 先说明几个概念. 电商网站采用在商品模块,常采用spu+sku的数据结构算法,这种算法可以将商品的属性和商品的基本信息分离,分开维护,这样我们就可以在不同的类目下自定义商品信息和分类的属性信息,我们的业务系统就可以存储不同门类的商品信息了 •SPU = Standard Product U...