Loading

C++顺序容器

顺序容器的定义#

一个容器就是一些特定类型对象的集合。
注:特定类型可以是 intfloatstringstruct xxx {} 等等。。。

容器又可以分为:顺序容器和关联容器。

顺序容器:元素排列按照其元素进入次序决定,与其元素的值无关。

顺序容器的分类#

顺序容器按照其存储结构和功能特性又可以分为如下:

容器名称 头文件 优缺点
vector(可变大小数组) #include <vector> 支持快速随机访问。但在尾部之外的位置插入或删除元素速度可能很慢
deque(双端队列) #include <deque> 支持快速随机访问。且在头尾位置插入或删除速度很快
list(双向链表) #include <list> 不支持随机访问,支持双向顺序访问。但在任何位置进行插入或删除元素速度都很快
forward_list(单向链表) #include <forward_list> 不支持随机访问,支持单向顺序访问。但在任何位置进行插入或删除元素速度都很快
array(固定大小数组) #include <array> 支持快速随机访问。但不能添加或删除元素操作(即改变数组大小操作)
string(字符串) #include <string> 专门用于存储字符。支持快速随机访问。在尾部插入或删除速度快

📌 支持随机访问,即可以通过元素下标访问

顺序容器的操作#

📌 所有容器都是类模版,要定义某种特殊的容器,必须声明数据类型

vector容器#

/*
 * @Description: 
 * @Author: 
 * @version: 
 * @Date: 2023-07-07 12:09:46
 * @LastEditors: 
 * @LastEditTime: 2023-09-21 14:30:22
 */
#include <iostream>
#include <vector>
using namespace std;

/* 
 * vector是一个可变大小数组的顺序容器 
 * 由于vector本身数据结构的原因,导致在除尾部之外的位置进行插入或
 * 删除元素操作,需要进行大量的元素移动操作,完成一次插入或删除元素
 * 操作效率很低。一般仅对尾部进行插入或删除操作。
 */

void print_vector_by_iterator(const vector<int> vec)
{
    vector<int>::const_iterator it; // 定义一个 vector<int> 迭代器
    // 通过迭代器遍历
    cout << "通过迭代器遍历,打印元素的值:" << endl;
    for (it = vec.begin(); it < vec.end(); it++) // 遍历容器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void print_vector_by_index(const vector<int> vec)
{
    cout << "通过下标遍历,打印元素的值:" << endl;
    for (int i = 0; i < vec.size(); i++)
    {
        cout << vec[i] << " ";
    }
    cout << endl;
}

int find_value_index(const vector<int> vec, int value)
{
    int idx = -1;
    for (int i = 0; i < vec.size(); i++)
    {
        if (vec[i] == value)
        {
            idx = i;
            break;
        } 
    }
    return idx;
}

int main()
{
    vector<int> ivec;         // 定义一个空的 vector<int> 容器
    vector<int>::iterator it; // 定义一个 vector<int> 迭代器

    // 在容器末尾插入 3 个数字,分别为1,2,3
    ivec.push_back(1); 
    ivec.push_back(2);
    ivec.push_back(3);

    // 通过迭代器遍历
    print_vector_by_iterator(ivec);

    // 通过下标遍历
    print_vector_by_index(ivec);

    // 查找值在vector中的索引
    int idx = find_value_index(ivec, 2);
    if (idx != -1)
        cout << "val 2 的索引 = " << idx << endl;
    else
        cout << "val 2 not find" << endl;

    // 删除尾部元素
    cout << "删除尾部元素,并打印结果" << endl;
    ivec.pop_back();
    print_vector_by_index(ivec);

    // 清空容器vector
    ivec.clear();
    cout << "ivec的元素数量:" << ivec.size() << endl;

    return 0;
}

deque容器#

/*
 * @Description: 
 * @Author: 
 * @version: 
 * @Date: 2023-09-21 14:46:35
 * @LastEditors: 
 * @LastEditTime: 2023-09-21 15:05:34
 */

#include <iostream>
#include <deque>
#include <string>
using namespace std;

/*
 * deque(双端队列)是一种顺序容器
 * deque可以在开头和末尾处进行操作,而且速度很快.
 * deque在除头尾除之外进行插入和删除元素操作效率很低
*/

void print_deque_by_iterator(const deque<string> deq)
{
    deque<string>::const_iterator it; // 定义一个 deque<string> 迭代器
    // 通过迭代器遍历
    cout << "通过迭代器遍历,打印元素的值:" << endl;
    for (it = deq.begin(); it < deq.end(); it++) // 遍历容器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void print_deque_by_index(const deque<string> deq)
{
    cout << "通过下标遍历,打印元素的值:" << endl;
    for (int i = 0; i < deq.size(); i++)
    {
        cout << deq[i] << " ";
    }
    cout << endl;
}

int main(void)
{
    deque<string> deq; // 定义一个双端队列

    deq.push_back("CN");
    deq.push_back("US");
    deq.push_back("UK");

    // 分别通过迭代器和下标遍历
    print_deque_by_iterator(deq);
    print_deque_by_index(deq);

    // 在双端队列头部插入元素"JS"
    deq.push_front("JS");
    print_deque_by_index(deq);

    // 删除尾部元素
    cout << "删除尾部元素后" << endl;
    deq.pop_back();
    print_deque_by_index(deq);

    // 删除头部元素
    cout << "删除头部元素后" << endl;
    deq.pop_front();
    print_deque_by_index(deq);

    // 清空deque容器
    deq.clear();
    cout << "deque的元素数量:" << deq.size() << endl;

    return 0;
}

list容器#

/*
 * @Description: 
 * @Author: 
 * @version: 
 * @Date: 2023-07-04 14:46:06
 * @LastEditors: 
 * @LastEditTime: 2023-10-07 11:08:39
 */

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

/*
 * list(双向链表)是一种常用的顺序容器
 * 它支持在任何位置进行插入或删除元素操作的速度都很快,
 * 但它不能进行随机访问,可以通过迭代器进行遍历
*/

void print_list(const list<int> lt)
{
    list<int>::const_iterator it;
    for (it = lt.begin(); it != lt.end(); it++)
    {   
        cout << *it << " ";
    }
    cout << endl;
}

/**
 * @description: delete specified element
 * @param {list<int>} &
 * @param {int} element
 * @return return true if delete successful, otherwise return false
 */
bool delete_specified_element(list<int> & lt, int element)
{
    bool rc = false;
    list<int>::iterator it;
    for (it = lt.begin(); it != lt.end(); it++)
    {   
        if (*it == element)
        {
            lt.erase(it);
            rc = true;
            break;
        }
    }

    return rc;
}

int main(void)
{
    int arr[] = {2, 3, 1, 6, 6};
    int len = sizeof(arr) / sizeof(arr[0]); // 计算arr的长度
    list<int> lt(arr, arr + len); // 定义一个list<int> 容器,并拷贝整型数组的所有元素

    // 由于不支持下标访问元素,故只能通过迭代器遍历list
    cout << "通过迭代器遍历list并打印其值:" << endl;
    print_list(lt);

    // 对容器中的元素排序
    cout << "对list容器元素队形排序,并打印list中元素的值:" << endl;
    lt.sort();
    print_list(lt);

    // 在头部和尾部插入元素
    cout << "在list头部插入一个值:" << endl;
    lt.push_front(0);
    print_list(lt);
    cout << "在list尾部插入一个值:" << endl;
    lt.push_back(4);
    print_list(lt);

    // 删除尾部元素
    cout << "删除list尾部元素:" << endl;
    lt.pop_back();
    print_list(lt);

    // 删除头部元素
    cout << "删除list头部元素:" << endl;
    lt.pop_front();
    print_list(lt);

    // 删除指定元素
    cout << "删除list指定元素2:" << endl;
    delete_specified_element(lt, 2);
    print_list(lt);


    // 删除所有等于元素的值
    cout << "删除所有等于元素的值6:" << endl;
    lt.remove(6);
    print_list(lt);

    // 判断容器是否为空
    cout << "判断容器list是否为空:" << endl;
    if (lt.empty())
        printf("list is empty\n");
    else
        printf("list is not empty\n");

    return 0;
}

作者:caojun97

出处:https://www.cnblogs.com/caojun97/p/17719196.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   eiSouthBoy  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu