当前位置: 首页 > article >正文

QT-【常用容器类】-QList类 QLinkedList类

QListQLinkedList 是 Qt 框架中提供的两个重要容器类,用于存储和管理一组数据。它们各自具有不同的特点和优缺点,适用于不同的场景。


1. QList 类概述

QList 是一个动态数组类,提供了对元素的快速随机访问。它的实现类似于 C++ 标准库中的 std::vector。通过 QList,开发者可以方便地管理一组相同类型的元素。

1.1 QList 的特性

  • 动态数组QList 可以自动扩展以容纳更多元素,适合用于大小不确定的列表。
  • 随机访问:支持快速的随机访问操作,时间复杂度为 O(1),适合频繁访问的场景。
  • 内存管理QList 使用引用计数来管理元素的内存,这意味着在列表中存储的对象将自动释放。
  • 支持复制QList 支持值语义和引用语义,可以安全地复制和传递。

1.2 QList 的基本用法

以下是 QList 的基本用法示例,包括创建、插入、删除和遍历元素。

cpp

#include <QList>
#include <QString>
#include <QDebug>

int main() {
    // 创建 QList
    QList<QString> list;

    // 添加元素
    list.append("Hello"); // 在末尾添加 "Hello"
    list.append("World"); // 在末尾添加 "World"

    // 插入元素
    list.insert(1, "Qt"); // 在索引 1 处插入 "Qt"

    // 访问元素
    qDebug() << list[0]; // 输出 "Hello"
    qDebug() << list.at(1); // 输出 "Qt"

    // 遍历元素
    for (const QString& str : list) {
        qDebug() << str; // 输出每个元素
    }

    // 删除元素
    list.removeAt(1); // 删除索引 1 的元素

    // 清空列表
    list.clear(); // 清空列表

    return 0;
}

1.3 QList 的常用方法

  • append(const T &value):在列表末尾添加一个元素。
  • insert(int i, const T &value):在指定索引处插入一个元素。
  • removeAt(int i):删除指定索引处的元素。
  • clear():清空列表,移除所有元素。
  • size():返回列表中的元素数量。
  • isEmpty():检查列表是否为空,返回布尔值。
  • indexOf(const T &value):查找元素并返回其索引,如果不存在则返回 -1。
  • contains(const T &value):检查列表是否包含某个元素。

1.4 QList 的性能分析

  • 插入和删除:在列表末尾插入或删除元素的时间复杂度是 O(1),在中间插入或删除的时间复杂度为 O(n),因为需要移动后续的元素。
  • 访问:访问元素的时间复杂度为 O(1),适合需要频繁随机访问的场景。
  • 内存使用QList 在内存使用上相对高效,但在进行大量插入和删除操作时,可能会导致频繁的内存重新分配。

2. QLinkedList 类概述

QLinkedList 是一个双向链表类,允许在列表的两端和中间位置进行快速插入和删除操作。其设计适合于需要频繁修改元素的场景。

2.1 QLinkedList 的特性

  • 双向链表:每个节点包含指向前一个和后一个节点的指针,允许双向遍历。
  • 插入和删除性能:在链表中间插入和删除的操作时间复杂度为 O(1),适合频繁修改的场景。
  • 不支持随机访问:访问列表元素的时间复杂度为 O(n),不适合需要频繁随机访问的场景。
  • 内存管理:同样使用引用计数来管理元素的内存。

2.2 QLinkedList 的基本用法

以下是 QLinkedList 的基本用法示例,包括创建、插入、删除和遍历元素。

cpp

#include <QLinkedList>
#include <QString>
#include <QDebug>

int main() {
    // 创建 QLinkedList
    QLinkedList<QString> linkedList;

    // 添加元素
    linkedList.append("Hello"); // 添加 "Hello"
    linkedList.append("World"); // 添加 "World"

    // 在头部插入元素
    linkedList.prepend("Qt"); // 在开头添加 "Qt"

    // 访问元素
    qDebug() << linkedList.first(); // 输出 "Qt"
    qDebug() << linkedList.last(); // 输出 "World"

    // 遍历元素
    for (const QString& str : linkedList) {
        qDebug() << str; // 输出每个元素
    }

    // 删除元素
    linkedList.removeFirst(); // 删除第一个元素
    linkedList.removeLast(); // 删除最后一个元素

    // 清空列表
    linkedList.clear(); // 清空链表

    return 0;
}

2.3 QLinkedList 的常用方法

  • append(const T &value):在链表末尾添加一个元素。
  • prepend(const T &value):在链表开头添加一个元素。
  • removeFirst():删除链表的第一个元素。
  • removeLast():删除链表的最后一个元素。
  • first():返回链表的第一个元素。
  • last():返回链表的最后一个元素。
  • size():返回链表中的元素数量。
  • isEmpty():检查链表是否为空,返回布尔值。

2.4 QLinkedList 的性能分析

  • 插入和删除:在链表的头部或尾部插入和删除的时间复杂度为 O(1),在链表中间插入或删除的时间复杂度也是 O(1),前提是你已经获得了该位置的迭代器。
  • 访问:访问元素的时间复杂度为 O(n),因此不适合频繁随机访问的场景。
  • 内存使用:由于每个节点都需要存储两个指针,QLinkedList 在内存占用上可能比 QList 更高,但在进行大量插入和删除操作时,QLinkedList 更加高效。

3. QList 和 QLinkedList 的比较

3.1 使用场景

  • QList

    • 适合需要频繁随机访问的场景,如查找、排序等操作。
    • 数据量不大且插入和删除操作不频繁时,QList 是一个理想选择。
  • QLinkedList

    • 适合需要频繁插入和删除操作的场景,特别是在中间位置。
    • 不需要随机访问时,可以使用 QLinkedList 来节省内存和提高性能。

3.2 优缺点总结

特性QListQLinkedList
存储方式动态数组双向链表
随机访问快速(O(1))慢(O(n))
插入/删除性能尾部 O(1),中间 O(n)头尾 O(1),中间 O(1)(需迭代器)
内存使用相对高效较高(每个节点需额外存储指针)
适用场景随机访问频繁,修改少插入删除频繁,随机访问少

4. 实际使用中的注意事项

在使用 QListQLinkedList 时,有一些注意事项可以帮助你更有效地利用这些容器:

  1. 选择合适的容器:根据具体需求选择 QListQLinkedList。如果频繁访问元素,选择 QList;如果频繁插入和删除元素,选择 QLinkedList

  2. 内存管理:虽然 Qt 的容器类会自动管理内存,但在使用自定义对象时,确保这些对象的析构函数正确实现,以避免内存泄漏。

  3. 避免不必要的复制:在需要传递 QListQLinkedList 给函数时,尽量使用引用(const QList<T>&const QLinkedList<T>&)来避免不必要的复制开销。

  4. 迭代器使用:在 QLinkedList 中频繁插入和删除时,使用迭代器可以提高效率。获取迭代器后,可以在 O(1) 的时间复杂度内进行插入和删除。

  5. 性能分析:在性能敏感的应用程序中,建议进行基准测试,以确定在特定情况下哪种容器表现更好。

5. 结论

QListQLinkedList 是 Qt 框架中非常重要的容器类,各自具有不同的优缺点和适用场景。QList 适合于需要频繁随机访问的情况,而 QLinkedList 更适合于频繁插入和删除的场景。


http://www.kler.cn/a/454359.html

相关文章:

  • stp生成树协议
  • Apache Solr XXE(CVE-2017-12629)--vulhub
  • 低代码开源项目Joget的研究——Joget7社区版安装部署
  • 寻找适合小户型的开源知识库open source knowledge base之路
  • ModbusTCP转Profinet:ABB机器人与PLC的高效连接
  • 《解锁 Python 数据挖掘的奥秘》
  • easegen将教材批量生成可控ppt课件方案设计
  • ubuntu服务器配置IP
  • Ubuntu下通过Docker部署MySQL服务器
  • 【LeetCode】726、原子的数量
  • 43. Three.js案例-绘制100个立方体
  • WPF+MVVM案例实战与特效(四十八)-实现一个自定义饼状图控件
  • Excel中match()函数
  • 【Docker命令】如何使用`docker exec`在容器内执行命令
  • [网鼎杯 2020 朱雀组]phpweb 1
  • 基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR
  • 抖音SEO短视频矩阵系统源码:短视频流量密码揭秘
  • openssl 安装及使用
  • 重温设计模式--C++迭代器种类和用法
  • linux如何抓包