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

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

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 优缺点总结

特性 QList QLinkedList
存储方式 动态数组 双向链表
随机访问 快速(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 更适合于频繁插入和删除的场景。

相关推荐
西猫雷婶2 小时前
python学opencv|读取图像(二十三)使用cv2.putText()绘制文字
开发语言·python·opencv
我要学编程(ಥ_ಥ)2 小时前
速通前端篇——JavaScript
开发语言·前端·javascript
汇能感知3 小时前
多光谱图像的处理和分析方法有哪些?
经验分享·笔记·科技
HEU_firejef3 小时前
设计模式——工厂模式
java·开发语言·设计模式
云计算DevOps-韩老师3 小时前
【网络云SRE运维开发】2024第52周-每日【2024/12/31】小测-计算机网络参考模型和通信协议的理论和实操考题
开发语言·网络·计算机网络·云计算·运维开发
fajianchen3 小时前
应用架构模式
java·开发语言
Code成立4 小时前
《Java核心技术 卷II》流的创建
java·开发语言·流编程
秋风&萧瑟4 小时前
【数据结构】双向循环链表的使用
数据结构·windows·链表
东京老树根5 小时前
SAP SD学习笔记23 - 无偿出荷(免费交货)与继续无偿出荷(继续免费交货)
笔记·学习
xing.yu.CTF5 小时前
HTML基础到精通笔记
前端·笔记·html