数据结构C++

简介

一、数组
  1. 静态数组
    array
  2. 动态数组
    2.1. vector
    2.2. priority_queue
    2.3. deque
    2.4. stack
    2.5. queue
二、单向链表
  forward_list
三、双向链表
  list
四、树
  1. set
  2. multiset
  3. map
  4. multimap
五、映射
  1. unordered_set
  2. unordered_multiset
  3. unordered_map
  4. unordered_multimap

程序员的世界里有一个经典的公式: 数据结构+算法=程序。

所以数据结构及算法的重要性就不用在此赘述了,下面直接进入正题。

在物理层面有以下五种常见的数据结构:

数据结构C++_第1张图片

 一、数组


 

1. 静态数组

在编译期确定数组大小,在运行期无法改变数组大小,所以称之为静态数组。

C++ 中的 array 由这种结构实现

复制代码

int main ()
{
    array a = {0,1,2,3,4,5,6,7,8,9};
    a[0] = 22;
    cout< 
  

复制代码

 

2. 动态数组

在运行期可动态改变数组大小,所以称之为动态数组。C++ 中的动态数组有两个,分别是 vector 和 deque。

2.1. vector

矢量,只能在末尾增删元素

数组大小的增长策略:每次增加的长度为原来的1倍(有些编译器增加0.5倍)。

这样可以保证增加元素的平均时间复杂度为O(1)。

复制代码

int main ()
{
    vector vv = {1,2,3,4};
    vv.push_back(12);// 在末尾添加元素
    vv.pop_back();// 在末尾删除元素
    vv.at(3);// 读取第三个元素
    vv[3];// 读写第三个元素
    vv.insert(vv.begin()+3, 12);// 将元素插到第三个位置上
    
    return 0;
}

复制代码

 

2.2. priority_queue

优先队列,默认由 vector 实现,也可由 deque 实现。它保证顶部元素始终是最大值,可用于实现堆排序。

复制代码

int main ()
{
    priority_queue pp;
    pp.push(12);
    pp.push(10);
    pp.push(11);
    pp.top();// 读取顶部元素
    pp.pop();// 弹出顶部元素
    
    return 0;
}

复制代码

 

2.3. deque

双端队列,可以在开头或末尾增删元素

复制代码

int main ()
{
    deque dd;
    dd.push_front(12);// 在开头添加元素
    dd.push_back(10);// 在结尾添加元素
    dd.insert(dd.begin()+1, 3);// 在位置1插入元素
    dd.front();// 读取开头元素
    dd.back();// 读取结尾元素
    dd[1]; // 读取第一个元素
    dd.pop_front();// 弹出开头元素
    dd.pop_back();// 弹出末尾元素

    return 0;
}

复制代码

 

2.4. stack

栈,默认由 deque 实现,也可由 list 或 vector 实现。是一种先进后出的数据结构

复制代码

int main ()
{
    stack ss;
    ss.push(12);// 添加元素
    ss.top();// 读取栈顶元素
    ss.pop();// 弹出栈顶元素

    return 0;
}

复制代码

 

2.5. queue

队列,默认由 deque实现,也可由 list 实现。是一种先进先出的数据结构

复制代码

int main ()
{
    queue qq;
    qq.push(12);// 添加元素
    qq.front();// 读取队首元素
    qq.pop();// 弹出队首元素

    return 0;
}

复制代码

 

二、单向链表


 

forward_list

只能从头到尾顺序遍历,不能逆序遍历,即没有 rbegin() 接口

复制代码

int main ()
{
    forward_list fl;
    fl.push_front(12);// 在开头添加元素
    fl.insert_after(fl.begin(), 11);
    fl.pop_front();// 在开头删除元素
    fl.remove(11);// 删除元素

    return 0;
}

复制代码

 

 三、双向链表


 

list

复制代码

int main ()
{
    list ll;
    ll.push_back(12);// 在末尾添加元素
    ll.push_front(10);// 在开头添加元素
    ll.back();// 读取末尾元素
    ll.front();// 读取开头元素
    ll.push_back(12);
    ll.unique();// 删除重复元素
    cout< 
  

复制代码

 

四、树


 数据结构C++_第2张图片

常见的树有二叉树、二叉搜索树、二叉平衡树、红黑树等。

C++ 中的 set multiset map multimap 是用二叉搜索树实现的,这种数据结构支持二分搜索,所以增删改查的复杂度都是O(logn)。

1. set

类似数学中的集合,set 中不能包含重复的元素,元素是排好序的,且不能被修改。

复制代码

int main ()
{
    set> ss;// 由小到大排序
    ss.insert(12);
    ss.insert(10);
    for(auto itr=ss.cbegin(); itr!=ss.cend(); itr++)cout<<*itr< 
  

复制代码

 

 2. multiset

与 set 类似,但可以包含重复元素

复制代码

int main ()
{
    multiset> ms;// 由小到大排序
    ms.insert(12);
    ms.insert(10);
    ms.insert(10);
    for(auto itr=ms.cbegin(); itr!=ms.cend(); itr++)cout<<*itr< 
  

复制代码

 

 3. map

元素由 (key,value) 对组成,接口与 set 类似,在插入与遍历元素时有些区别

复制代码

int main ()
{
    map mm;
    mm[1] = 1;// 插入元素 (1,1)
    mm.insert(make_pair(2,2));// 插入元素 (2,2)
    for(auto itr=mm.cbegin(); itr!=mm.cend(); itr++)
        cout<<"("<first<<","<second<<")"< 
  

复制代码

 

 4. multimap

复制代码

int main ()
{
    multimap mm;
    mm.insert(make_pair(1,10));// 插入元素 (1,10)
    mm.insert(make_pair(1,11));// 插入元素 (1,11)
    mm.insert(make_pair(2,2));// 插入元素 (2,2)
    for(auto itr=mm.cbegin(); itr!=mm.cend(); itr++)// 遍历所有元素
        cout<<"("<first<<","<second<<")"<first<<","<second<<")"< 
  

复制代码

 

 五、映射


 

 数据结构C++_第3张图片

映射类似数学中的函数,每一个 key 对应一个 value,写成函数表达式为:value=f(key),其中 f 被称为哈希函数。

C++11 中的 unordered_set unordered_multiset unordered_map unordered_multimap 是用映射实现的,这种数据结构可以在O(1)的时间复杂度下访问单个元素,效率高于二叉搜索树(O(logn)),但是遍历元素的效率比二叉搜索树低。

1. unordered_set

接口与 set 类似

2. unordered_multiset 

接口与 multiset 类似

3. unordered_map 

接口与 map 类似

4. unordered_multimap 

接口与 multimap 类似

复制代码

你可能感兴趣的:(C++基础)