八、C++ 标准模板库-STL概述

C++ 标准模板库-STL概述

一、基本概念

1.1 泛型程序设计

C++ 语言的核心优势之一就是便于软件的重用,重用在两个方面有体现:

  1. 面向对象的思想:继承和多态,标准类库
  2. 泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL

简单地说就是使用模板的程序设计法。将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法。

标准模板库 (Standard Template Library) 就是一些常用数据结构和算法的模板的集合。有了STL,不必再写大多的标准数据结构和算法,并且可获得非常高的性能。

1.2 STL中基本的概念

容器: 可容纳各种数据类型的通用数据结构,是类模板

迭代器: 可用于依次存取容器中元素,类似于指针

算法: 用来操作容器中的元素的函数模板

二、容器概述

容器指可以用于存放各种类型的数据( 基本类型的变量,对象等)的数据结构,都是类模版,分为三种:

  1. 顺序容器

    vector, deque,list

  2. 关联容器

    set, multiset, map, multimap

  3. 容器适配器

    stack, queue, priority_queue

对象被插入容器中时,被插入的是对象的一个复制品。许多算法,比如排序,查找,要求对容器中的元素进行比较,有的容器本身就是排序的,所以,放入容器的对象所属的类,往往还应该重载 == 和 < 运算符。

2.1 顺序容器

顺序容器并非指容器内的元素是排序的,元素的插入位置同元素的值无关。有vector,deque,list 三种。

vector 指动态数组。元素在内存连续存放。随机存取任何元素都能在常数时间完成,在尾端增删元素具有较佳的性能(大部分情况下是常数时间)。头文件是< vector>

deque指双向队列。元素在内存连续存放。随机存取任何元素都能在常数时间完成(但次于vector)。在两端增删元素具有较佳的性能(大部分情况下是常数时间)。

list指双向链表。元素在内存不连续存放。在任何位置增删元素都能在常数时间完成。 不支持随机存取。

2.2 关联容器

关联容器有以下几个特点:

  1. 元素是排序的
  2. 插入任何元素,都按相应的排序规则来确定其位置
  3. 在查找时具有非常好的性能
  4. 通常以平衡二叉树方式实现, 插入和检索的时间都是 O(log(N))

有两类:

  1. set/multiset(头文件 < set>)

    set 即集合。 set中不允许相同元素, multiset中允许存在相同的元素。

  2. map/multimap(头文件 < map>)

    map与set的不同在于map中存放的元素有且仅有两个成员变量,一个名为first,另一个名为second, map根据first值对元素进行从小到大排序,并可快速地根据first来检索元素。

    map同multimap的不同在于是否允许相同first值的元素

2.3 容器适配器

容器适配器有3类:stack、queue、priority_queue。

stack指栈。是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项(栈顶的项)。 后进先出。头文件是< stack>

queue指队列。插入只可以在尾部进行,删除、检索和修改只允许从头部进行。 先进先出。头文件是< queue>。

priority_queue指优先级队列。最高优先级元素总是第一个出列。头文件是< queue>。

2.4 成员函数

顺序容器和关联容器中都有的成员函数:

begin 返回指向容器中第一个元素的迭代器
end 返回指向容器中最后一个元素后面的位置的迭代器
rbegin 返回指向容器中最后一个元素的迭代器
rend 返回指向容器中第一个元素前面的位置的迭代器
erase 从容器中删除一个或几个元素
clear 从容器中删除所有元素
front :返回容器中第一个元素的引用
back : 返回容器中最后一个元素的引用
push_back : 在容器末尾增加新元素
pop_back : 删除容器末尾的元素
erase :删除迭代器指向的元素(可能会使该迭代器失效),或删除一个区间,返回被删除元素后面的那个元素的迭代器

三、迭代器

3.1 基本概念

迭代器用于指向顺序容器和关联容器中的元素,用法和指针类似,有const 和非 const两种。通过迭代器可以读取它指向的元素,通过非const迭代器还能修改其指向的元素。

定义一个容器类的迭代器的方法可以是:

容器类名::iterator 变量名;

容器类名::const_iterator 变量名;

访问一个迭代器指向的元素:

* 迭代器变量名

迭代器上可以执行 ++ 操作, 以使其指向容器中的下一个元素。如果迭代器到达了容器中的最后一个元素的后面,此时再使用它,就会出错,类似于使用NULL或未初始化的指针一样。

3.2 迭代器示例

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> v; //一个存放int元素的数组,一开始里面没有元素
    v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4);

    vector<int>::const_iterator i; //常量迭代器
    for( i = v.begin();i != v.end();++i )
        cout << * i << ",";
    cout << endl;

    vector<int>::reverse_iterator r; //反向迭代器
    for( r = v.rbegin();r != v.rend();r++ )
        cout << * r << ",";
    cout << endl;

    vector<int>::iterator j; //非常量迭代器
    for( j = v.begin();j != v.end();j ++ )
        * j = 100;
    for( i = v.begin();i != v.end();i++ )
        cout << * i << ",";
}

输出:

1,2,3,4,

4,3,2,1,

100,100,100,100,

3.3 迭代器类别

3.3.1 双向迭代器

若p和p1都是双向迭代器,则可对p、 p1可进行以下操作:

++p, p++ 使p指向容器中下一个元素
--p, p-- 使p指向容器中上一个元素
* p 取p指向的元素
p = p1 赋值
p == p1 , p!= p1 判断是否相等、不等

3.3.2 随机访问迭代器

若p和p1都是随机访问迭代器,则可对p、 p1可进行以下操作:

双向迭代器的所有操作
p += i 将p向后移动i个元素
p -= i 将p向向前移动i个元素
p + i 值为: 指向 p 后面的第i个元素的迭代器
p - i 值为: 指向 p 前面的第i个元素的迭代器
p[i] 值为: p后面的第i个元素的引用
p < p1, p <= p1, p > p1, p>= p1

3.3.3 容器和迭代器

容器 容器对应的迭代器
vector 随机访问
deque 随机访问
list 双向
set/multiset 双向
map/multimap 双向
stack 不支持迭代器
queue 不支持迭代器
priotiry_queue 不支持迭代器

四、算法简介

4.1 基本概念

算法就是一个个函数模板, 大多数在< algorithm> 中定义。

STL中提供能在各种容器中通用的算法,比如查找,排序等算法通过迭代器来操纵容器中的元素。许多算法可以对容器中的一个局部区间进行操作,因此需要两个参数,一个是起始元素的迭代器,一个是终止元素的后面一个元素的迭代器。比如,排序和查找。有的算法返回一个迭代器。比如 find() 算法,在容器中查找一个元素,并返回一个指向该元素的迭代器。

算法可以处理容器,也可以处理普通数组。

4.2 算法示例

template<class InIt, class T>
InIt find(InIt first, InIt last, const T& val);

first 和 last 这两个参数都是容器的迭代器,它们给出了容器中的查找区间起点和终点[first,last)。区间的起点是位于查找范围之中的,而终点不是。 find在[first,last)查找等于val的元素用 == 运算符判断相等。

函数返回值是一个迭代器。如果找到,则该迭代器指向被找到的元素。如果找不到,则该迭代器等于last。

五、STL中“大”、“小”、“相等”的概念

5.1 基本概念

关联容器内部的元素是从小到大排序的

  1. 有些算法要求其操作的区间是从小到大排序的,称为“ 有序区间算法”

    例: binary_search

  2. 有些算法会对区间进行从小到大排序,称为“排序算法”

    例: sort

  3. 还有一些其他算法会用到“大”,“小”的概念

使用STL时,在缺省的情况下,以下三个说法等价:

  1. x比y小
  2. 表达式“ x < y”为真
  3. y比x大

关于“相等”:

  1. 有时,“ x和y相等”等价于“ x==y为真”

    例:在未排序的区间上进行的算法,如顺序查找find

    ……

  2. 有时“ x和y相等”等价于“ x小于y和y小于x同时为假”

    例:

    有序区间算法,如binary_search

    关联容器自身的成员函数find

    ……

5.2 程序示例

#include<vector>
#include<algorithm>
using namespace std;

class A
{
    int v;
    public:
        A(int v):v(v) { }
        bool operator<(const A &a) const{
            cout<<v<<"<"<<a.v<<"?"<<endl;
            return false;
        }
        bool operator==(const A &a) const{
            cout<<v<<"=="<<a.v<<"?"<<endl;
            return v==a.v;
        }
};

int main()
{
    //重载运算符 < 后的二分查找
    A a[] = {A(1), A(2), A(3), A(4), A(5)};
    cout<<binary_search(a, a+5, A(9));

    return 0;
}

输出:

3<9?

2<9?

1<9?

9<1?

1

折半查找,最后找到1没有更多的可以找了。比较9是否小于1,结果为假;比较1是否小于9,结果为假;这时候认为9==1,输出1。

六、小结

  1. STL 三个基本概念:容器、迭代器、算法
  2. 容器分为顺序容器、关联容器、容器适配器
  3. 顺序容器分为vector(动态数组)、deque(双向队列)、list(双向链表)
  4. 关联容器分为set/multiset、map/multimap
  5. 容器适配器stack、queue、priority_queue
  6. 迭代器分为双向迭代器、随机访问迭代器,不同的容器可以使用的迭代器类别不同
  7. 算法就是一个个函数模板, 大多数在< algorithm> 中定义
  8. STL 中的”大“、”小“、”相等“等概念可以自己定义,可能和常规意义上的概念不同
时间: 2024-10-14 02:58:37

八、C++ 标准模板库-STL概述的相关文章

PKU C++程序设计实习 学习笔记6 标准模板库STL

标准模板库STL 8.1 STL概述 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用:1.面向对象的思想:继承和多态,标准类库  2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法. 标准模

实验8 标准模板库STL

一.实验目的与要求: 了解标准模板库STL中的容器.迭代器.函数对象和算法等基本概念. 掌握STL,并能应用STL解决实际问题. 二.实验过程: 完成实验8标准模板库STL中练习题,见:http://acm.hpu.edu.cn/contest.php?cid=1020,密码c++08,共有5道题.将答题过程简单记录到实验过程中. 将答题结果写到实验结果中,并根据答题结果进行分析.反思,将其写到实验分析中,并写上实验时间.

标准模板库(STL)学习探究之vector容器

标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据.为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>构造函数. Vectors 包含着一系列连续存储的元素,其行为和数组类

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

摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动态数组)STL vector进行分析和总结. 引言 因为前段时间对台大的机器学习基石和技法课程进行了学习,发如今详细的实现中经常涉及到各种类型的数据结构,比方线性表.二叉树.图等,在使用这些数据结构时感到有些吃力.主要是对一些主要的数据结构理解的不够.所以趁着暑假假期.近期一段时间总会抽出时间复习一

标准模板库--STL

标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法.标准模板库 (Standard

C++ 标准模板库STL 队列 queue 使用方法与应用介绍

C++ 标准模板库STL 队列 queue 使用方法与应用介绍 queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型. 定义queue对象的示例代码如下: queue<int> q1; queue<double> q2; queue的基本操作有: 入队,如例:q.push(x); 将x接到队列的末端. 出队,如例:

【c++】标准模板库STL入门简介与常见用法

一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部分,使用STL开发系统可以提高开发效率. 2.容器(Containers) 容器类是可以包含其它对象的模板类,如向量类(vector).链表类(list).双向队列类(deque).集合类(set)和映射类(map)等.其中vector.list.deque为序列式容器,set.map为关联式容器.

C++的标准模板库(STL)简介

STL(Standard Template Library,标准模板库)是C++对泛型编程思想的实现,最早是惠普实验室开发的.在被引入C++之前该技术就已经存在了很长的一段时间.后来STL成为ANSI/ISO C++标准的一部分.各个C++厂商也有各自相应的模板库,这些库效率可能很高,但可移植性不一定好. 在C++标准中,STL被组织为下面的17个头文件:<algorithm>.<deque>.<functional>.<iterator>.<arra

C++标准模板库STL

思维导图 C++标准模板库 参考 容器类详解 常用容器方法总结 原文地址:https://www.cnblogs.com/yusq77/p/11220885.html